Проблема в основном решена после некоторого раунда копания в oracle_enhanced_adapter.rb
.
Проблема заключалась в том, что слишком много таблиц в локальной схеме (многие EBA_%, EVT_%, EMP_%, SMP_%
таблицы были созданы там одновременно в какой-то момент), архивные таблицы были включены в дамп и выбор из словарей данных занял 14 секунд выполнить.
Чтобы исправить скорость, я сделал три вещи:
- Отброшены все ненужные таблицы (около 250 из 500)
- Исключенные архивные таблицы из дампа схемы
- Кэшируется результат длительного выполнения запроса
Это позволило сократить время от перенесения дампа / схемы для оставшихся 350 таблиц с 90 минут до 15 секунд. Более чем достаточно быстро.
Мой код выглядит следующим образом (для вдохновения, а не для копирования и вставки - этот код довольно специфичен для моей базы данных, но вы должны быть в состоянии понять идею). Вам необходимо создать временную таблицу вручную. У меня уходит примерно 2 или 3 минуты - все еще слишком долго для генерации при каждой миграции, и в любом случае это довольно статично =)
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