[ Oracle PL/SQL ] 挿入速度は FOR LOOP より FORALL の方が圧倒的に高速

Pocket

ここでは、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 秒
スポンサーリンク


Pocket

Leave a Comment

Your email address will not be published. Required fields are marked *