forall
ステートメント自体はループではありません。
配列のすべての要素を一度にSQLエンジンに送信します。これにより、SQLは、PL / SQLエンジンに戻ってデータを取得しなくても、行を挿入できます。
つまりFORALL
、通常のFORループで発生するコンテキスト切り替えを削除します。
これは簡単なトレースで示すことができます。検討:
SQL> alter session set sql_trace=true;
Session altered.
SQL> declare
2 TYPE ebRBKTable IS TABLE OF EBTDCCRBK%ROWTYPE INDEX BY PLS_INTEGER;
3 rbkTable ebRBKTable;
4 begin
5
6 for idx in 1..100000
7 loop
8 rbkTable(idx).BDADDUSERID := dbms_random.string('a', 10);
9 end loop;
10
11 forall idx in 1..rbkTable.count
12 insert into EBTDCCRBK values rbkTable(idx);
13 commit;
14
15 end;
16 /
SQLトレースでは、次のように表示されます。
INSERT INTO EBTDCCRBK
VALUES
(:B1 )
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.07 0.07 1 724 3066 100000
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.07 0.07 1 724 3066 100000
vs regluarループ:
SQL> alter session set sql_trace=true;
Session altered.
SQL> declare
2 TYPE ebRBKTable IS TABLE OF EBTDCCRBK%ROWTYPE INDEX BY PLS_INTEGER;
3 rbkTable ebRBKTable;
4 begin
5
6 for idx in 1..100000
7 loop
8 rbkTable(idx).BDADDUSERID := dbms_random.string('a', 10);
9 end loop;
10
11 for idx in 1..rbkTable.count
12 loop
13 insert into EBTDCCRBK values rbkTable(idx);
14 end loop;
15 commit;
16
17 end;
18 /
PL/SQL procedure successfully completed.
SQL> alter session set sql_trace=false;
トレースファイルは次のことを示しています。
INSERT INTO EBTDCCRBK
VALUES
(:B1 )
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 100000 3.33 3.24 1 689 104216 100000
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 100001 3.33 3.24 1 689 104216 100000
バージョンのトレースファイルはFORALL
1回しか実行されなかったことに注意してください。つまり、SQLエンジンが1回のヒットで作業を実行しました。バリアントではFOR LOOP
、SQLエンジンは100kの実行を行い、同じジョブを実行するためにより多くのCPUを使用しました(多くの単一操作を実行する必要があり、セッションは挿入された行ごとにpl / sql->sqlからコンテキストを切り替えていたため) 。