レール:rake db:移行*非常に*スロー-ポリティクスにOracle
-
09-09-2019 - |
質問
を使用していレールの oracleenhanced
アダプタの作成新しいインターフェースのための遺産。
データベースの移動作業の成功と考えられることが起こらないかも長時間前レーキが終了します。データベースの変更がかなり迅速にアンドリュー(1または2秒)ですが、 db/schema.db
ダンプにかかり、時間を完了します。(例移動します。)
この比較的大きなスキーマ(約150テーブル)が、思べきではないこの長いダンプはそれぞれ表する。
直しとかは出来ないんですか速するだけできる schema.db
は変更で指定された移行した。るのは僕でこのスキーマダンプ。
理解しているこ schema.db
で作成された試験データベースから各時に、この場合、ある大きなチャンクのデータベースの論理テーブルトリガーを入れていないの schema.rb
とにかく、そのレーキ試験は、次のようなものである。(全ての課題を必要とすることを選択である。)
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
解決
すべての移行がデータベースに適用された後、その後のdbをすくい:通話のDBを移行:スキーマ:現在のデータベーススキーマからschema.rbファイルが生成するタスクをダンプ
。デシベル:スキーマ:すべてのテーブルのリストを取得するための呼び出しアダプタの「テーブル」の方法をダンプし、各テーブルの「インデックス」方法と「列」メソッドを呼び出します。あなたはActiveRecordの-oracle_enhancedアダプタ宝石のoracle_enhanced_adapter.rbファイルにこれらの方法で使用されているSQL SELECT文を見つけることができます。基本的にはすべての情報を見つけるために、すべて%またはUSER%のデータ・ディクショナリ表からの選択を行います。
私は、異なるスキーマの多いデータベースでそれを使用する場合(パフォーマンスは、データベース内のテーブルの合計数によって影響を受ける可能性があるとして - だけではなく、自分のスキーマ内に)当初、私は元のOracleアダプタの問題を持っていたので、私はいくつかの最適化を行いましたオラクルでは、アダプタを強化。 (私はそれが「インデックス」または各テーブルに対して実行され、「列」の方法のいずれかであると思われる)あなたのケースでは遅いである方法を見つけるために良いでしょう。
メソッド呼び出しはとても長い時間がかかっているあなたが特定できるように、あなたはoracle_enhanced_adapter.rbファイルにいくつかのデバッグメッセージを置く場合は、この問題をデバッグするための一つの方法鍬は以下のようになります。
他のヒント
問題はほぼ解決した後も掘りを通 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