Oracle SQL TRUNCATE文の使い方|DELETEとの違いと高速化

Oracle Master Silver

大量のデータを削除する際、「処理が終わらない」「UNDO表領域が溢れた」という経験はありませんか?

Oracle TRUNCATE文は、テーブル内の全データを瞬時に消去し、ストレージ容量を解放する強力なコマンドです。しかし、DELETEとの違いを正しく理解せずに使うと、取り返しのつかない事故につながるリスクもあります。

本記事では、TRUNCATE文の基本構文から、DELETE文との詳細な比較、HWM(ハイウォーターマーク)のリセットによるパフォーマンス向上の仕組み、そして実務で遭遇するエラーへの対処法を、Oracle Database 19c を基準に解説します。

💰 【PR】Oracleエンジニアの市場価値、調べてみませんか?

Oracleのスキルは需要が高く、特定の資格や経験を持っていると年収が大幅にアップするケースがあります。まずはIT専門のエージェントで非公開求人をチェックしてみませんか?


結論・最短手順(やることリスト)

時間がない方のための、TRUNCATE文実行の要点です。

  1. 対象確認: 全件削除して良いテーブルか再確認する(WHERE句は使えません)。
  2. 制約確認: 外部キー(FK)参照されていないか確認する。
  3. バックアップ: 戻せないので、必要なら CREATE TABLE ... AS SELECT 等で退避する。
  4. 実行: TRUNCATE TABLE コマンドを実行する(自動コミットされます)。

1. TRUNCATE文とは? 仕組みとメリット

TRUNCATE文は、テーブルのデータを「物理的に切り捨てる」DDL(データ定義言語)です。

DELETE文との決定的な違い(DML vs DDL)

通常の DELETE 文は DML(データ操作言語)であり、1行ずつ削除を行い、その都度「削除した」という履歴(UNDOデータ)を記録します。そのため、大量データの削除には時間がかかり、ロールバック(取り消し)が可能です。

一方、TRUNCATE文 は DDL です。データの行を個別に処理するのではなく、データが格納されている「領域(エクステント)」そのものを解放します。

  • 超高速: ログ生成が最小限(データディクショナリの更新分のみ)であるため。
  • 即時確定: 実行と同時にコミット(確定)され、ロールバックできません

HWM(High Water Mark)のリセット

Oracleのテーブルには「ここまでデータが入ったことがある」という水位線(HWM)があります。

  • DELETEの場合: データは消えますが、HWMは下がりません。空き地ができても、Oracleは「データがあるかもしれない」とみなしてスキャンするため、検索速度が改善しないことがあります。
  • TRUNCATEの場合: HWMがリセット(初期化)されます。これにより、未使用領域がOSや表領域に返還され、次回の全表スキャン(Full Table Scan)が劇的に高速化します。

【図解:HWMの動き】

初期状態(データ満タン)
[■■■■■■■■■■] <- HWM

DELETE実行後(中身は空だが枠は残る)
[□□□□□□□□□□] <- HWM (位置は変わらない = 検索時にここまで読む)

TRUNCATE実行後(枠ごと撤去)
[ ] <- HWM (リセットされる = 検索が速い)

2. TRUNCATEとDELETEの比較表

実務でどちらを使うべきか判断するための比較表です。

特徴TRUNCATE文DELETE文
SQLの種類DDL (データ定義言語)DML (データ操作言語)
条件指定 (WHERE)不可 (全件削除のみ)可能
処理速度非常に高速遅い (データ量に比例)
ロールバック不可 (自動コミット)可能 (COMMIT前なら)
トリガー起動されない (DELETEトリガー無視)される
HWM (水位線)リセットされる維持される
必要な権限DROP ANY TABLEDELETE 権限
主な用途ワークテーブルの初期化、データ総入替特定データの削除、業務ロジック

💰 【PR】Oracleエンジニアの市場価値、調べてみませんか?

Oracleのスキルは需要が高く、特定の資格や経験を持っていると年収が大幅にアップするケースがあります。まずはIT専門のエージェントで非公開求人をチェックしてみませんか?


3. 基本構文と実行手順

基本構文

TRUNCATE TABLE [スキーマ名.]テーブル名 [DROP STORAGE | REUSE STORAGE];
  • DROP STORAGE (デフォルト): 解放された領域を表領域へ返却します。
  • REUSE STORAGE: 領域を保持します(直後に同量のデータをINSERTする場合、再確保の負荷を減らせます)。

実行例(実機用コード)

以下は、ユーザー SCOTT が所有する WORK_LOG テーブルを空にする例です。

※SQL内にはマルチバイト文字を含めていません。コメントは適宜読み飛ばしてください。

前提:

  • 対象テーブル: WORK_LOG
  • 実行ユーザーはテーブル所有者、または DROP ANY TABLE 権限保持者。
-- 1. Check current data count (Optional)
SELECT count(*) FROM WORK_LOG;

-- 2. Create backup just in case (Recommended)
-- Creating a backup table using CTAS (Create Table As Select)
CREATE TABLE WORK_LOG_BK AS SELECT * FROM WORK_LOG;

-- 3. Execute TRUNCATE
TRUNCATE TABLE WORK_LOG;

-- 4. Verify the result
SELECT count(*) FROM WORK_LOG;

【実行結果の解説】

コマンドが成功すると Table truncated. と表示されます。直後の SELECT 結果は 0 件となります。この操作は即時確定しており、ROLLBACK; を実行してもデータは戻りません。


4. トラブルシューティング(よくあるエラー)

TRUNCATE実行時によく遭遇するエラーとその対処法です。

ORA-02266: 親キー・レコードが外部キー制約で参照されています

原因: 他のテーブル(子テーブル)から、削除しようとしているテーブル(親テーブル)のデータを参照している外部キー制約(Foreign Key)が存在するため。

対処:

  1. 子テーブル側のデータを先に削除する、または制約を無効化する。
  2. TRUNCATECASCADE オプションを付ける(Oracle 12c以降)。
    • 注意: CASCADE は子テーブルのデータも道連れに削除します。非常に危険なため、基本は「制約無効化」で対応します。

【回避策:制約の一時無効化】

-- Disable the constraint on the child table
ALTER TABLE CHILD_TABLE DISABLE CONSTRAINT FK_CONSTRAINT_NAME;

-- Now you can truncate the parent table
TRUNCATE TABLE PARENT_TABLE;

-- Enable the constraint again (Ensure data consistency first)
ALTER TABLE CHILD_TABLE ENABLE CONSTRAINT FK_CONSTRAINT_NAME;

ORA-00054: リソース・ビジー、NOWAITが指定されていました…

原因: 別のセッションがそのテーブルをロックしています(例:誰かが INSERT や UPDATE を行い、コミットしていない)。

対処: ロックしているセッションがコミットまたはロールバックするのを待つか、当該セッションを特定して終了させます。


5. 運用・セキュリティ上の注意点

1. 権限管理

TRUNCATEはデータを削除する操作ですが、必要な権限は DELETE 権限ではなく、テーブルを「変更・破棄」する権限(所有者であるか、DROP ANY TABLE システム権限)が必要です。一般のアプリケーションユーザーに過剰な権限を与えないよう注意してください。

2. バックアップの重要性

「一瞬で消える」「戻せない」のが最大のリスクです。本番環境で実行する際は、必ず事前に EXPDP (Data Pump) や CTAS でバックアップを取得してください。

3. フラッシュバック機能の制限

Oracleの「フラッシュバックテーブル(Flashback Table)」機能は、通常過去の時点に戻せますが、TRUNCATEされたテーブルはDDLによってオブジェクトID等は変わらないものの、データ構造がリセットされるため、フラッシュバックで戻すことができません(Flashback Database機能を使用している場合を除く)。


6. FAQ(よくある質問)

Q1: TRUNCATEした後、インデックスはどうなりますか?

A1: データと一緒にインデックスの中身も空になりますが、インデックスの定義(構造)自体は残ります。特別な再構築(REBUILD)は通常不要ですが、統計情報はリセットされるため、必要に応じて統計情報の再取得を推奨します。

Q2: ID列(IDENTITY列)の連番はリセットされますか?

A2: バージョンや設定によりますが、基本的にはリセットされません。連番を1から戻したい場合は、別途 ALTER TABLE … MODIFY … RESTART START WITH 1; 等の操作が必要です。

Q3: 特定のパーティションだけTRUNCATEできますか?

A3: はい、可能です。パーティション化されたテーブルであれば、TRUNCATE TABLE テーブル名 PARTITION (パーティション名); で、特定の区画だけを高速に空にできます。


7. まとめ

TRUNCATE文は、Oracle Databaseの運用において非常に便利なツールです。

  • 高速: UNDOログをほぼ生成せず、数百万件のデータも数秒で削除可能。
  • 効率化: HWMをリセットし、ストレージ容量の解放と検索パフォーマンスを向上。
  • 注意: WHERE句なし、ロールバック不可、トリガー不発。

「定期的なログテーブルのクリーニング」や「テスト環境の初期化」には最適ですが、操作は慎重に行ってください。まずは開発環境で DELETE との挙動の違いを体感してみましょう。


[参考]
Oracle Database SQL言語リファレンス 19c

💰 【PR】Oracleエンジニアの市場価値、調べてみませんか?

Oracleのスキルは需要が高く、特定の資格や経験を持っていると年収が大幅にアップするケースがあります。まずはIT専門のエージェントで非公開求人をチェックしてみませんか?

コメント

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