高速に全件削除、TRUNCATE TABLE文

ORACLE
20160211-1

ORACLEにおいて、テーブル内のデータを無条件に全件削除する際に使用するTRUNCATE TABLE文(テーブルの切捨て)について解説していきます。
DELETE文の条件なしでの削除に比べて、圧倒的に高速で処理出来るため重宝します。

スポンサーリンク

TRUNCATE TABLE文、高速にテーブル内のデータを全件削除

-- テーブルの切捨て(割り当てた領域を解除)
-- ※DROP STORAGEは省略可能
TRUNCATE TABLE test_table DROP STORAGE;

-- テーブルの切捨て(割り当てた領域を保持)
TRUNCATE TABLE test_table REUSE STORAGE;

TRUNCATE TABLE文(DDL)は、テーブル内のデータを無条件に全件削除(テーブルの切捨て)を行います。
DELETE文(DML)の条件なしでの削除に比べて、圧倒的に高速で処理出来ます。データ量が多い場合、DELETE文はかなりの時間(10分以上かかるケースも)がかかりますが、TRUNCATE TABLE文は1秒以内~数秒程度で処理出来ます。

オプションで、割り当て済みの領域を削除と、保持を選ぶことが出来ます。

  • DROP STORAGE:割り当て済みの領域を削除(省略した場合はこちら)
  • REUSE STORAGE:割り当て済みの領域を保持

使用には、DROP権限が必要です。

HWM(ハイウォーターマーク)も下がります。

テーブルに対応するインデックスも切捨てます。

共有プールに保持されている対象テーブルに関係するSQL文の解析結果や実行計画がクリアされます。

スポンサーリンク

使用する際の注意点

便利なTRUNCATE TABLE文ですが、使用する際には注意点もあります。

  • DDL文であるため、実行前にトランザクションが暗黙的にコミットされる(DML文であるDELETE文と同じようには使えない)
  •  ROLLBACK文で処理を取り消すことは出来ない(COMMIT文も不要)
  •  外部キー制約の親である表に対しては、実施できない(自己参照型の外部キーは可能)
  •  DELETEを起動条件としているトリガーは作動しない

オプションによる差異

割り当てた領域を削除するか保持するかのオプションによる結果の差異を確認します。

-- 切捨て前割り当て情報
SELECT SEGMENT_NAME
      ,ROUND(BYTES/1024/1024,2) MBYTES
FROM   DBA_SEGMENTS
WHERE  SEGMENT_NAME IN('TEST_TABLE1','TEST_TABLE2')
;

SEGMENT_NAME      MBYTES
--------------- --------
TEST_TABLE1      1307.19
TEST_TABLE2      1307.19

-- 切捨て
TRUNCATE TABLE test_table1 DROP STORAGE;
TRUNCATE TABLE test_table2 REUSE STORAGE;

-- 切捨て後割り当て情報
SELECT SEGMENT_NAME
      ,ROUND(BYTES/1024/1024,2) MBYTES
FROM   DBA_SEGMENTS
WHERE  SEGMENT_NAME IN('TEST_TABLE1','TEST_TABLE2')
;

SEGMENT_NAME      MBYTES
--------------- --------
TEST_TABLE1         0.06
TEST_TABLE2      1307.19

また、処理時間ですがREUSE STORAGE(割り当て済みの領域を保持)の方が若干かかります。また、割り当て済みの領域が多いほど時間がかかります。

使い分けですが、削除後に同量のデータを再度登録する場合は、REUSE STORAGE(割り当て済みの領域を保持)を使用し、それ以外の場合はDROP STORAGE(割り当て済みの領域を削除)を使用します。

まとめ

テーブル内のデータを無条件に全件削除する際に使用するTRUNCATE TABLE文、処理が高速なので非常に重宝します。
しかし、気をつけなくてはいけない点もあります。特にROLLBACKが効かない点は注意が必要です。誤ってROLLBACKを使用してしまった場合、取り返しがつきません。
注意しましょう。

関連

タイトルとURLをコピーしました