Frage

Ich bin mit Schienen mit dem oracleenhanced Adapter eine neue Schnittstelle für eine Legacy-Anwendung zu erstellen.

Datenbankmigrationen erfolgreich arbeiten, aber eine unglaublich lange Zeit, bevor Rake Oberflächen nehmen. Die Datenbank-Änderungen passieren ziemlich schnell (1 oder 2 Sekunden), aber die db/schema.db Dump dauert über eine Stunde zu beenden. (Siehe Beispiel Migration unten).

Es ist ein relativ großes Schema (etwa 150 Tabellen), aber ich bin sicher, es sollte nicht so lange nehme jede Tabelle Beschreibung auskippen.

Gibt es trotzdem, dies zu beschleunigen, indem nur den letzten schema.db nehmen und die Änderung die Migration auf dem angegebene Anwendung? Oder bin ich in der Lage dieses Schema Dump ganz überspringen?

Ich verstehe das schema.db verwendet wird, um die Testdatenbank jedes Mal neu zu erstellen, aber dieser Fall, gibt es einen großen Teil der Datenbanklogik in Tabelle Trigger, die in den schema.rb ohnehin nicht enthalten sind, so dass die Rake-Tests sind keine gut zu uns auf jeden Fall. (Das ist eine ganz andere Frage, die ich brauche an einem anderen Punkt zu sortieren.)

dgs@dgs-laptop:~/rails/voyager$ time rake db:migrate
(in /home/dgs/rails/voyager)
== 20090227012452 AddModuleActionAndControllerNames: migrating ================
-- add_column(:modules, :action_name, :text)
   -> 0.9619s
   -> 0 rows
-- add_column(:modules, :controller_name, :text)
   -> 0.1680s
   -> 0 rows
== 20090227012452 AddModuleActionAndControllerNames: migrated (1.1304s) =======


real    87m12.961s
user    0m12.949s
sys 0m2.128s
War es hilfreich?

Lösung

Nachdem alle Migrationen auf Datenbank angewendet werden dann db Rake: Migration Anrufe db: schema:. Dump Aufgabe schema.rb Datei aus der aktuellen Datenbank-Schema zu generieren

db: schema: dump Anruf Adapters „Tabellen“ Methode, um die Liste aller Tabellen, dann für jede Tabelle als „Indizes“ -Methode und „Spalten“ Methode zu erhalten. Sie können SQL-SELECT-Anweisungen finden, die in diesen Verfahren in Activerecord-oracle_enhanced-Adapter gem der oracle_enhanced_adapter.rb Datei verwendet werden. Im Grunde ist es tut wählt aus ALLEN% oder USER% Data Dictionary-Tabellen alle Informationen zu finden.

Am Anfang hatte ich Probleme mit dem ursprünglichen Oracle-Adapter, wenn ich es mit Datenbanken mit vielen verschiedenen Schemata verwendet (wie Leistung könnte durch die Gesamtzahl der Tabelle in der Datenbank betroffen sein - nicht nur in Ihrem Schema), und daher habe ich einige Optimierungen in Oracle verbesserten Adapter. Es wäre gut, um herauszufinden, welche Methoden in Ihrem Fall langsam ist (ich vermute, dass es entweder „Indizes“ oder „Spalten“ Methode sein könnte, das für jede Tabelle ausgeführt wird).

Eine Möglichkeit, Hacke, dieses Problem zu debuggen wäre, wenn Sie einige Debug-Meldungen in oracle_enhanced_adapter.rb Datei setzen würden, so dass Sie erkennen können, welche Methode Anrufe so lange Zeit nehmen.

Andere Tipps

Problem meist nach einiger Grab Runde in oracle_enhanced_adapter.rb gelöst.

Das Problem kam auf viel zu viele Tabellen im lokalen Schema (viele EBA_%, EVT_%, EMP_%, SMP_% Tabellen hatte dort zufälligerweise an einem gewissen Punkt erstellt wurde), Archivtabellen in der Deponie und eine ausgewählte aus den Daten Wörterbücher enthalten sind unter 14 Sekunden auszuführen .

Um die Geschwindigkeit zu beheben, habe ich drei Dinge:

  1. Dropped alle nicht benötigten Tabellen (etwa 250 von 500)
  2. Ausgeschlossen Archivtabellen aus dem Schema-Dump
  3. das Ergebnis der langen laufende Abfrage Cached

Dies verbesserte die Zeit von der Migration / schema-Dump für die restlichen 350 Tabellen von etwa 90 Minuten bis etwa 15 Sekunden. Mehr als schnell genug.

Ihr Code wie folgt (für Inspiration nicht das Kopieren und Einfügen - dieser Code ist zu meiner Datenbank ziemlich spezifisch, aber Sie sollten die Idee bekommen sein können). Sie müssen die temporäre Tabelle manuell erstellen. Es dauert etwa 2 bis 3 Minuten für mich zu tun - immer noch zu lange bei jeder Migration zu erzeugen, und es ist ziemlich statisch sowieso =)

module ActiveRecord
  module ConnectionAdapters
    class OracleEnhancedAdapter
      def tables(name = nil)
        select_all("select lower(table_name) from all_tables where owner = sys_context('userenv','session_user')  and table_name not like 'A!_%' escape '!' ").inject([]) do | tabs, t |
          tabs << t.to_a.first.last
        end
      end


      # TODO think of some way to automatically create the rails_temp_index table 
      #
      #   Table created by: 
      #   create table rails_temp_index_table as 
      #   SELECT lower(i.index_name) as index_name, i.uniqueness, 
      #          lower(c.column_name) as column_name, i.table_name
      #    FROM all_indexes i, user_ind_columns c
      #    WHERE  c.index_name = i.index_name 
      #       AND i.owner = sys_context('userenv','session_user')
      #       AND NOT exists  (SELECT uc.index_name FROM user_constraints uc 
      #              WHERE uc.constraint_type = 'P' and uc.index_name = i.index_name);

        def indexes(table_name, name = nil) #:nodoc:

              result = select_all(<<-SQL, name)
                SELECT index_name, uniqueness, column_name
                  FROM rails_temp_index_table
                 WHERE table_name = '#{table_name.to_s.upcase}'
                  ORDER BY index_name
              SQL

              current_index = nil
              indexes = []

            result.each do |row|
                if current_index != row['index_name']
                  indexes << IndexDefinition.new(table_name, row['index_name'], row['uniqueness'] == "UNIQUE", [])
                  current_index = row['index_name']
                end

                indexes.last.columns << row['column_name']
              end

              indexes
            end
end
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top