MySQL 入門

MySQL テーブルデータのクリア (DELETE vs TRUNCATE)

DELETE 文と TRUNCATE TABLE 命令は、どちらもデータテーブルからデータを削除するために使用されますが、データベースエンジンにおける低レイヤーの処理が完全に異なります。その結果、パフォーマンス、ログの記録、および機能的な特性に顕著な差異が生じます。

1. DELETE 文:1行ずつの処理

DELETE は、DML(データ操作言語 / Data Manipulation Language)に分類されるコマンドです。DELETE 文を実行すると、たとえ対象がテーブル内の全行であっても、MySQL エンジンはそれを「一連の独立したシングル行操作」として扱います。

-- 特定の条件に一致する行を削除
DELETE FROM orders WHERE status = 'cancelled';

-- テーブル内のすべての行を削除
DELETE FROM orders;

DELETE を実行すると、データベースエンジンはテーブルをスキャンし、設定した基準に一致するすべての行を特定します。その後、関連する制約(トリガー / Triggers や 外部キー / Foreign Keys など)をチェックし、レコードを1つずつ削除します。この処理が1行ごとに行われるため、MySQL はトランザクションログに各削除操作を記録します。

これが、DELETE がトランザクションをサポートしている理由です。InnoDB のようなストレージエンジン(Storage Engine)を使用している場合、誤って実行したことに気づけば、コミット(Commit)前にロールバック(Rollback)してデータを復旧させることができます。

しかし、この1行ずつ処理する方法はコンピューティングリソースの消費が非常に激しいです。数百万行のデータを含むテーブルで無条件の DELETE を実行すると、処理速度が非常に遅くなり、大量の CPU リソースを消費するだけでなく、トランザクションログのサイズが肥大化する原因となります。

2. TRUNCATE TABLE 命令:テーブルのリセット

TRUNCATE TABLE は、DDL(データ定義言語 / Data Definition Language)に分類されるコマンドです。これは行をスキャンして削除するのではなく、本質的に既存のテーブルを一度削除(Drop)し、同じ構造で再作成(Recreate)する仕組みで動作します。

TRUNCATE TABLE orders;

テーブルを再作成するため、TRUNCATE は行ごとのスキャンを行いません。すべての行レベルの制約やトリガーを無視し、トランザクションログに個別のデータ削除を記録することもありません。これにより、テーブルにどれほど多くのレコードが含まれていても、実行速度はほぼ一瞬(インスタント)です。

最も重要なポイントは、テーブルに AUTO_INCREMENT(オートインクリメント)カラムが含まれている場合、TRUNCATE はそのカウンターを初期値(通常は 1)にリセットすることです。DELETE ではこのようなリセットは行われず、オートインクリメントのカウンターは削除前の位置から継続して増加します。

3. 機能の全面比較

特性DELETETRUNCATE TABLE
コマンドタイプDML (データ操作言語)DDL (データ定義言語)
実行パフォーマンス遅い (1行ずつ処理)極めて速い (直接削除して再構築)
WHERE 句サポート (細かなフィルタリングが可能)非サポート (全テーブルクリアのみ)
自増カラム (Auto-Increment)現在のカウント値を維持初期値にリセット
トランザクション対応ロールバック可能 (Rollback)通常は暗黙のコミット、ロールバック不可
トリガー (Triggers)DELETE トリガーが発火するいかなるトリガーも発火しない

判断基準のリファレンス:

  • 特定の行をフィルタリングする必要がありますか?WHERE 句を伴う DELETE を使用
  • フィルタリングは不要で、オートインクリメント ID をリセットしたいですか?TRUNCATE TABLE を使用
  • フィルタリングは不要で、ID はリセットしたくないが、データセットが非常に巨大ですか?TRUNCATE TABLE を推奨(速度面で有利)

4. 制約とセキュリティメカニズム

TRUNCATE は DDL コマンドであるため、MySQL におけるトランザクションの挙動が異なります。多くの設定において、TRUNCATE の実行は「暗黙のコミット(Implicit Commit)」を引き起こします。つまり、この操作をロールバックすることはできません。一度実行されると、データは即座に消失します。

さらに、現在のテーブルが別のテーブルから FOREIGN KEY(外部キー)制約によって参照されている場合、TRUNCATE は実行に失敗します。DELETE も参照整合性に違反する場合は失敗しますが、DELETEWHERE 句を使用できるため、これらの関連関係を尊重しながら特定の行を削除するという「粒度(Granularity)」を持った操作が可能です。一方、TRUNCATE を実行するには、まず外部キーを削除するか無効化する必要があります。