Oracle で MERGE ステートメントを使用して、何百万ものレコードの一括挿入/更新を行っています。他のオプションとして、FORALL を使用して BULKCOLLECT を使用してからコミットすることもできますが、ループを維持する必要があるため、この操作もパフォーマンスを低下させます。マージ操作全体の完了後にコミットすると、パフォーマンスが低下します。バッチコミットのような挿入/更新の 10000 行ごとにマージステートメント内にコミット頻度を設定する方法を知りたいです。
2 に答える
MERGE ステートメントは 1 つのステートメントであるため、定義上、複数のトランザクションにまたがることはできません。(ACID の A は原子性を表します。)
ソース テーブルとターゲット テーブルの両方のマージ条件 (ON 句) にインデックスがない場合、単一の MERGE ステートメントを N 個のマージ ステートメントに変換すると、いずれかに対して単一のスキャンを実行していた場合と同様に、実行が大幅に遅くなります。ソースおよび/またはターゲット、あなたはそれらのNを行うつもりです. 1 回のフル テーブル スキャンが遅いと思われる場合は、100 万行ごとに 100 回実行してみてください。
正直に言うと、単一の MERGE をより多くのステートメントに切り刻むと、より多くの作業が行われるため、遅くなります。より多くのステートメントを実行しているため、解析のオーバーヘッドが多くなり、より多くのコミットを実行しているため、コミットの実行中にプログラムが待機するため、よりシリアライズされます。単一のステートメントを複数のステートメントに分割する唯一の正当な理由は、再開可能性に懸念がある場合 (いや、ジョブは 3 時間後に失敗し、4 時間しかありませんでした!)、またはトランザクション管理のオーバーヘッド (UNDO と ORA-01555 の)が問題になります。
このプロセスで CPU を使用できる場合は、MERGE ステートメントに対して PARALLEL ヒントを使用して、実行速度が向上するかどうかを確認することを検討してください。同様に、MERGE ステートメントがターゲット テーブルの一部の行にのみ影響を与える場合、マージ対象の列のインデックスによってパフォーマンスが向上する可能性があります。