ここでは、FOR LOOP と FORALL それぞれでデータベースへ 10 万件分のデータを insert する処理速度を比較しています。
スポンサーリンク
本当はスクリプトの実行時間を取得するだけにしようと思っていましたが、急遽 データベースへの挿入スピード比較実験となりました。
比較実験用スクリプト
ここで使用するスクリプトになります。
CREATE OR REPLACE PROCEDURE HSM00.TEST
IS
vStartTime NUMBER; -- 開始時間
vEndTime NUMBER; -- 終了時間
vExecuteTime NUMBER; -- 実行時間
-- 10万件分のテストデータを格納するバッファ
TYPE numbers_type IS TABLE OF NUMBER INDEX BY PLS_INTEGER;
numbers numbers_type;
BEGIN
-- 10万件分のテストデータを設定する
FOR i IN 1..100000 LOOP
numbers(i) := i;
END LOOP;
-- 処理開始時間を取得 1/100 秒単位で取得される
vStartTime := DBMS_UTILITY.GET_TIME;
-- for loop で10万件のデータをINSERTする
for i IN 1..100000 LOOP
-- COL1(varchar2) COL2(number) COL3(date)
insert into ZTABLE(COL1, COL2, COL3) values('STR', numbers(i), SYSDATE);
END LOOP;
COMMIT; -- コミットする
-- 処理終了時間を取得
vEndTime := DBMS_UTILITY.GET_TIME;
-- 処理実行時間を計算(秒単位に変換)
vExecuteTime := ( vEndTime - vStartTime ) / 100;
DBMS_OUTPUT.PUT_LINE('FOR LOOP 処理実行時間 = ' || vExecuteTime || ' 秒');
-- 一旦全部削除
delete from ZTABLE;
COMMIT; -- コミットする
-- 処理開始時間を取得
vStartTime := DBMS_UTILITY.GET_TIME;
-- forall で10万件のデータをINSERTする
forall i IN 1..100000
-- COL1(varchar2) COL2(number) COL3(date)
insert into ZTABLE(COL1, COL2, COL3) values('STR', numbers(i), SYSDATE);
COMMIT; -- コミットする
-- 処理終了時間を取得
vEndTime := DBMS_UTILITY.GET_TIME;
-- 処理実行時間を計算(秒単位に変換)
vExecuteTime := ( vEndTime - vStartTime ) / 100;
DBMS_OUTPUT.PUT_LINE('FORALL 処理実行時間 = ' || vExecuteTime || ' 秒');
-- 後始末
delete from ZTABLE;
COMMIT; -- コミットする
END;
/
実行結果
多少のばらつきはありますが、大体このような計測結果となりました。ずいぶんと違うものです。比較用のスクリプトが間違っているのかもしれません。FORALL での insert が圧倒的に高速です。
- FOR LOOP 処理実行時間 = 6.51 秒
- FORALL 処理実行時間 = .23 秒