大量のデータを削除する際、「処理が終わらない」「UNDO表領域が溢れた」という経験はありませんか?
Oracle TRUNCATE文は、テーブル内の全データを瞬時に消去し、ストレージ容量を解放する強力なコマンドです。しかし、DELETEとの違いを正しく理解せずに使うと、取り返しのつかない事故につながるリスクもあります。
本記事では、TRUNCATE文の基本構文から、DELETE文との詳細な比較、HWM(ハイウォーターマーク)のリセットによるパフォーマンス向上の仕組み、そして実務で遭遇するエラーへの対処法を、Oracle Database 19c を基準に解説します。
💰 【PR】Oracleエンジニアの市場価値、調べてみませんか?
Oracleのスキルは需要が高く、特定の資格や経験を持っていると年収が大幅にアップするケースがあります。まずはIT専門のエージェントで非公開求人をチェックしてみませんか?
結論・最短手順(やることリスト)
時間がない方のための、TRUNCATE文実行の要点です。
- 対象確認: 全件削除して良いテーブルか再確認する(WHERE句は使えません)。
- 制約確認: 外部キー(FK)参照されていないか確認する。
- バックアップ: 戻せないので、必要なら
CREATE TABLE ... AS SELECT等で退避する。 - 実行:
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 TABLE 等 | DELETE 権限 |
| 主な用途 | ワークテーブルの初期化、データ総入替 | 特定データの削除、業務ロジック |
💰 【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)が存在するため。
対処:
- 子テーブル側のデータを先に削除する、または制約を無効化する。
TRUNCATEにCASCADEオプションを付ける(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専門のエージェントで非公開求人をチェックしてみませんか?




コメント