Pregunta

Estoy usando los carriles con el adaptador oracleenhanced para crear una nueva interfaz para una aplicación antigua.

migraciones de bases de datos funcionan con éxito, pero tienen un tiempo increíblemente largo período de tiempo antes acabados rastrillo. Los cambios de bases de datos ocurren con bastante rapidez (1 ó 2 segundos), pero el vertedero db/schema.db tarda más de una hora en completarse. (Véase el ejemplo la migración a continuación.)

Es un esquema relativamente grande (alrededor de 150 tablas), pero estoy seguro de que no debe tomar este tiempo para volcar cada descripción de la tabla.

¿Hay alguna forma de acelerar este proceso con sólo tomar la última schema.db y aplicar el cambio especificado en la migración a ella? O soy capaz de saltarse este esquema volcado por completo?

Yo entiendo que esta schema.db se utiliza para crear la base de datos de prueba desde cero cada vez, pero este caso, hay una gran parte de la lógica de la base de datos en la tabla de disparadores que no están incluidos en el schema.rb de todos modos, por lo que las pruebas de desprendimiento hay bueno con nosotros en cualquier caso. (Eso es una cuestión totalmente diferente que tengo que resolver en algún otro momento.)

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
¿Fue útil?

Solución

Después de todas las migraciones se aplican a la base de datos a continuación, el rastrillo db: migrate llamadas db: schema:. Tarea de volcado para generar el archivo schema.rb del esquema de base de datos actual

db: schema: método de "tablas" volcado de adaptador de llamada para obtener la lista de todas las tablas, a continuación, para cada tabla llama al método "índices" y el método "columnas". Puede encontrar instrucciones SELECT de SQL que se utilizan en estos métodos en el archivo oracle_enhanced_adapter.rb-activerecord oracle_enhanced-adaptador de joya. Básicamente lo hace desde selecciona TODAS% o diccionario de datos% USUARIO tablas para encontrar toda la información.

Al principio tuve problemas con el adaptador original de Oracle cuando lo usé con bases de datos con gran cantidad de diferentes esquemas (como el rendimiento puede verse afectado por el número total de tabla en la base de datos - no sólo en el esquema) y por lo tanto hice algunas optimizaciones en Oracle mejorado adaptador. Sería bueno averiguar qué métodos son lentos en su caso (sospecho que podría ser o bien "índices" o método de "columnas" que se ejecuta para cada tabla).

Una azada forma de depurar este problema sería si desea poner algunos mensajes de depuración en el archivo oracle_enhanced_adapter.rb por lo que se podía identificar qué llamadas a métodos están tomando tanto tiempo.

Otros consejos

Problema resuelto principalmente después de algún ronda de excavación en oracle_enhanced_adapter.rb.

El problema se reducía a demasiadas tablas en el esquema local (muchas mesas EBA_%, EVT_%, EMP_%, SMP_% se habían creado allí casualmente en algún momento), las tablas de archivos que se incluyen en el vertedero y un selecto de los diccionarios de datos que tienen 14 segundos para ejecutar .

Para fijar la velocidad, hice tres cosas:

  1. retiró todos los cuadros que no sean necesarios (alrededor de 250 de 500)
  2. tablas de archivos excluidos de la volcado esquema
  3. En caché el resultado de la consulta de larga ejecución

Esto mejoró el tiempo desde el vertedero de la migración / esquema para las 350 mesas restantes de unos 90 minutos a unos 15 segundos. Más de lo suficientemente rápido.

Mi código de la siguiente manera (en busca de inspiración no copiar y pegar - el código es bastante específica a mi base de datos, pero debe ser capaz de obtener la idea). Es necesario crear manualmente la tabla temporal. Se tarda unos 2 o 3 minutos para que haga - siendo demasiado largo para generar con cada migración, y es bastante estática de todos modos =)

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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top