web-dev-qa-db-ja.com

Oracle 11g-低速の並列挿入選択を最適化する方法は?

以下の並列挿入ステートメントの実行を高速化します。約8000万件のレコードを挿入する予定であり、完了するまでに約2時間かかります。

INSERT /*+ PARALLEL(STAGING_EX,16) APPEND NOLOGGING */ INTO STAGING_EX (ID, TRAN_DT, 
RECON_DT_START, RECON_DT_END, RECON_CONFIG_ID, RECON_PM_ID) 
SELECT /*+PARALLEL(PM,16) */ SEQ_RESULT_ID.nextval, sysdate, sysdate, sysdate, 
'8a038312403e859201405245eed00c42', T1.ID FROM PM T1 WHERE STATUS = 1 and not 
exists(select 1 from RESULT where T1.ID = RECON_PM_ID and CREATE_DT >= sysdate - 60) and 
UPLOAD_DT >= sysdate - 1 and (FUND_SRC_TYPE = :1) 

存在しない列の結果をキャッシュすると、挿入が高速化されると考えています。キャッシュを実行するにはどうすればよいですか?インサートをスピードアップする他の方法はありますか?

Enterprise Managerからのプラン統計については、以下を参照してください。また、ステートメントが並行して実行されていないことにも気づきました。これは正常ですか?

insert-select plan statistics from Oracle em

編集:ところで、シーケンスはすでに1Mにキャッシュされています

9
robertdi

特にネストされたループが発生する可能性がある場合は、より多くのバインド変数を使用してみてください。次のような場合に使用できることに気づきました

CREATE_DT >= :YOUR_DATE instead of CREATE_DT >= sysdate - 60 

これは、更新クエリの他の部分全体がまだ7900万のうち800万であるにもかかわらず、実行プランの最下部に1億8000万の実行がある理由を説明すると思います。

3
Avias

統計を改善します。推定行数は1ですが、実際の行数は700万を超えています。これにより、実行プランはハッシュ結合の代わりにネストされたループを使用します。ネストされたループは少量のデータに対してより適切に機能し、ハッシュ結合は大量のデータに対してより適切に機能します。これを修正するのは、関連するテーブルに正確な最新の統計があることを確認するのと同じくらい簡単かもしれません。これは通常、デフォルト設定で統計を収集することで実行できます(例:exec dbms_stats.gather_table_stats('SIRS_UATC1', 'TBL_RECON_PM');)。

それでもカーディナリティの推定が改善されない場合は、/*+ dynamic_sampling(5) */などの動的サンプリングヒントを使用してみてください。このような長時間実行されるクエリの場合、より良い計画につながるのであれば、事前にデータをサンプリングするために少し余分な時間を費やす価値があります。

オブジェクトレベルの並列処理の代わりにステートメントレベルの並列処理を使用します。これはおそらく並列SQLで最も一般的な間違いです。オブジェクトレベルの並列処理を使用する場合、ヒントはオブジェクトのエイリアスを参照する必要があります。 11gR2以降、オブジェクトの指定について心配する必要はありません。このステートメントには、INSERT /*+ PARALLEL(16) APPEND */ ...という1つのヒントのみが必要です。 NOLOGGINGは実際のヒントではないことに注意してください。

5
Jon Heller

私は2つの大きな問題を見ることができます:

1-ヒント並列(選択中)いいえ動作しません。これは次のようになるはずです+ PARALLEL(T1,16)

2-SELECTは最適ではありません。NOTIN式を避けた方がよいでしょう。

0
usergray