SQL DELETEとTRUNCATEの主な違い

データ削除のSQL DELETEとTRUNCATEを比較します。ログ記録、ロールバック対応、パフォーマンス、トリガー、使い分けについて詳しく解説します。

DML

詳細な説明

SQL DELETEとTRUNCATEの主な違い

DELETETRUNCATE はどちらもテーブルから行を削除しますが、根本的に異なる仕組みで動作し、それぞれ異なるシナリオに適しています。

DELETE

DELETE FROM orders
WHERE status = 'cancelled' AND order_date < '2024-01-01';

特徴:

  • 行を1つずつ削除する(行レベルの操作)
  • WHERE句による選択的な削除が可能
  • 各行でDELETEトリガーが発火する
  • 完全にログに記録される(削除された各行がトランザクションログに記録)
  • トランザクション内でロールバックが可能
  • 自動採番カウンターはリセットされない
  • 大量削除では低速

TRUNCATE

TRUNCATE TABLE temp_import_data;

特徴:

  • データページの割り当てを解除してすべての行を削除する(ページレベルの操作)
  • WHERE句は使用不可(すべてを削除する)
  • ほとんどのデータベースでDELETEトリガーが発火しない
  • 最小限のログ記録(ページの割り当て解除のみ記録)
  • ロールバックの動作はデータベースにより異なる(PostgreSQLではサポート、MySQLでは非サポート)
  • 自動採番カウンターが初期値にリセットされる
  • すべての行の削除ではかなり高速

比較表

機能 DELETE TRUNCATE
WHERE句 あり なし
トリガー 発火する 発火しない
ログ記録 完全 最小限
ロールバック 可能 データベースに依存
速度(全行) 低速 高速
自動採番 維持 リセット
外部キー 行ごとにチェック 参照されている場合はブロック

DELETEを使用する場合

  • 条件に基づいて特定の行を削除する場合
  • 監査証跡のためにトリガーが発火する必要がある場合
  • 確実なロールバック機能が必要な場合
  • 外部キー参照があるテーブルから削除する場合

TRUNCATEを使用する場合

  • ステージングテーブルや一時テーブルのクリア
  • テスト実行間のテストデータのリセット
  • トリガーが不要な場合の全データ削除
  • 数百万行をクリアする必要がありパフォーマンスが重要な場合

安全な削除パターン

DELETE FROM logs WHERE created_at < '2024-01-01' LIMIT 10000;

バッチ削除により長時間実行されるトランザクションを回避します。影響行数がゼロになるまで繰り返します。

DELETEとTRUNCATEの使い分けを理解することは、データの整合性と監査要件を維持しながら効率的にデータライフサイクルを管理するための鍵です。

ユースケース

データ保持システムが、監査準拠のために個別の期限切れレコードの削除にはDELETEを使用し、ETL処理完了後のナイトリーステージングテーブルの迅速なリセットにはTRUNCATEを使用する場面。

Try It — SQL Formatter

フルツールを開く