私は単純なPL/SQLプロシージャを1つのカーソルで持っています。それを反復処理します。各反復では、(ビジネスロジックをデータに実行した後に)UPDATE文を作成します。Oracle PL/SQLの遅延更新
しかし、反復がたくさんある場合(数万)、すべての反復で1つのUPDATE文があるため、これは非常に遅くなる可能性があります。
これらの更新を何らかの形で「遅延」させて、すべてを一度に(したがってずっと速く)実行する方法はありますか?
編集:Oracleの11
私は単純なPL/SQLプロシージャを1つのカーソルで持っています。それを反復処理します。各反復では、(ビジネスロジックをデータに実行した後に)UPDATE文を作成します。Oracle PL/SQLの遅延更新
しかし、反復がたくさんある場合(数万)、すべての反復で1つのUPDATE文があるため、これは非常に遅くなる可能性があります。
これらの更新を何らかの形で「遅延」させて、すべてを一度に(したがってずっと速く)実行する方法はありますか?
編集:Oracleの11
あなたが(すべて一緒forループ回避)ストレートSQLを使用する方法を見つけ出すことができない場合、あなたはおそらくPL/SQLのBULKコレクション機能を使用してパフォーマンスを向上させることができるようになります。
構文抜粋
LOOP
FETCH c_orders
BULK COLLECT INTO v_order_ids, v_currency_codes, v_amounts_local
LIMIT 100;
EXIT WHEN v_row_count = c_orders%ROWCOUNT;
v_row_count := c_orders%ROWCOUNT;
FOR i IN 1..v_order_ids.count LOOP
v_amounts_usd(i) := currency_convert (v_amounts_local(i),
v_currency_codes(i));
END LOOP;
FORALL i IN 1..v_order_ids.count
UPDATE open_orders /* bulk bind */
SET amount_usd = v_amounts_usd(i)
WHERE order_id = v_order_ids(i);
END LOOP;
+1と聞こえて実行される他の作業と比較して無視できる程度です。 forall http://www.dba-oracle.com/oracle_tips_rittman_bulk%20binds_FORALL.htmの他の記事 – bpgergo
ですべての可能な場合は、更新文でビジネスロジックを実行するようにしてください。それはずっと速くなるでしょう。
私は問題の分析を見ませんが、私は多くの前提と結論に飛びつく人々を見ています。私は次のことをお勧めし、より体系的なアプローチを取得するには:更新ジョブは、時間のほとんどは、更新ジョブがある前
ほとんどの時間を費やして実際の問題に取り組んでいます。
問題は、Oracleがロールバック・セグメントを維持していることです。 1つのトランザクションで変更が多いほど、遅くなります。ビジネスロジックを分割し、1000回の更新ごとに 'COMMIT; 'を追加できませんか? – sjngm
@sjngm、これは一般的に悪い考えです。 Tom Kyteには、http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:4951966319022など、十分な説明があります。 – DCookie
@snjgmの場合、ロールバック・セグメント、イテレーションとセレクトによって発生するロールバック・セグメントのために減速しません。ロールバック・セグメントの更新は、同じ答えを出すためにここに来た – steve