1

DML 実行時の PL/SQL スクリプトのパフォーマンスに関して 2 つの質問があります。もちろん、これEXECUTE IMMEDIATEが最も遅いためforallbulk挿入などがあります。私の質問は

  1. 3 つの異なるテーブルでデータを操作する必要があります。Table1(データの挿入)、Table2(データの更新)、およびTable3データの削除。これらはすべて、カーソルを使用してフェッチされた値に基づいて行われます。問題は、ここでより効率的なものは何ですか?
    • これらの各ステートメントを個別のForallブロックに入れますか? すなわち
fetch cursor
loop
   forall loop for table 1
   forall loop for table 2
   forall loop for table 3
end loop

また

  • グローバル ループを作成し、そのループ内でこれらのステートメントを実行します。
fetch cursor loop
    for i IN array.count 
    loop
       3 statements for DML
    end loop end loop

さて、私の2番目の質問

  1. ループでレコードを削除する効率的な方法は何ですか? カーソルを介して削除するレコードの値を取得しました。それらを削除する効率的な方法は何でしょうか?

PS: 私の書式設定を実行してください

4

1 に答える 1

4

最も効率的なアプローチは、カーソルからフェッチされたデータがプロシージャの実行期間にわたって安定していると仮定して、3つのSQLステートメントを作成することです。

INSERT INTO table1( list_of_columns )
  <<your SELECT statement>>

UPDATE table2
   SET (<<list of columns>>) = (<<your SELECT statement joined to table2>>)
 WHERE EXISTS( <<your SELECT statement joined to table2>> );

DELETE FROM table3
 WHERE EXISTS( <<your SELECT statement joined to table3>> );

ステートメントが3つのDMLステートメントのそれぞれで異なる結果を返す可能性がある場合はSELECT、カーソルを使用し、データをPL / SQLコレクションに一括収集し、コレクションをループして一貫性を確保するというパフォーマンスヒットを受け入れるのが理にかなっています。結果。FORALLそれを実行している場合は、SQLエンジンとPL / SQLエンジン間のコンテキストシフトが少ないため、3つのステートメントを使用する方が効率的です。

ループ内のレコードを削除する効率的な方法は何ですか?削除するレコードの値をカーソルで取得しました。今、それらを削除する効率的な方法は何でしょうか?

質問がよくわかりません。またはのFORALL場合と同じようにループを実行しませんか?INSERTUPDATE

FORALL i IN l_array.first .. l_array.last
  DELETE FROM some_table
   WHERE some_key = l_array(i);

それとも別の質問をしていますか?

于 2011-12-01T19:02:59.800 に答える