「テーブルの中身を一瞬で全部消したい」
──そんなときに便利なのが、SQLのTRUNCATE文です。
しかし、同じくデータ削除に使うDELETE
と何が違うのか、混乱する方も多いのではないでしょうか?
この記事では、TRUNCATEの使い方、特徴、DELETEとの違い、使用時の注意点を初心者向けにやさしく解説します。
間違って使うと取り返しがつかないこともあるので、しっかり理解しておきましょう。
TRUNCATE文って何?

TRUNCATEの基本的な役割
TRUNCATEは、テーブル内のすべてのデータを即座に削除するSQL文です。
ただし、テーブル自体の構造(列の定義など)は残ります。
基本的な書き方
TRUNCATE TABLE テーブル名;
実際の使用例
-- usersテーブルの全データを削除
TRUNCATE TABLE users;
-- logsテーブルの全データを削除
TRUNCATE TABLE logs;
-- test_dataテーブルの全データを削除
TRUNCATE TABLE test_data;
TRUNCATEのイメージ
実行前
users テーブル
+----+----------+-----+
| id | name | age |
+----+----------+-----+
| 1 | 田中太郎 | 25 |
| 2 | 佐藤花子 | 30 |
| 3 | 山田次郎 | 28 |
+----+----------+-----+
TRUNCATE実行
TRUNCATE TABLE users;
実行後
users テーブル(構造は残っているが、データは空)
+----+------+-----+
| id | name | age |
+----+------+-----+
(データなし)
データベース別の書き方
MySQL
TRUNCATE TABLE users;
-- または
TRUNCATE users; -- TABLEは省略可能
PostgreSQL
TRUNCATE TABLE users;
-- 外部キー制約がある場合
TRUNCATE TABLE users RESTART IDENTITY CASCADE;
SQL Server
TRUNCATE TABLE users;
SQLite
-- SQLiteはTRUNCATEをサポートしていない
-- 代わりにDELETEを使用
DELETE FROM users;
DELETE文との違いを詳しく比較

基本的な違いの表
項目 | TRUNCATE | DELETE |
---|---|---|
削除対象 | 全行(条件指定不可) | 条件付き削除が可能 |
処理速度 | 非常に早い | 遅い(特に大量データ) |
ログ出力 | 最小限 | 各行の削除をログに記録 |
WHERE句 | 使用不可 | 使用可能 |
トリガー | 通常は発動しない | 削除トリガーが実行される |
オートインクリメント | リセットされる | そのまま継続 |
ロールバック | 基本的に不可 | トランザクションで可能 |
処理速度の違い
TRUNCATE(早い)
-- 100万件のデータでも瞬時に削除
TRUNCATE TABLE large_table;
DELETE(遅い)
-- 100万件のデータだと時間がかかる
DELETE FROM large_table;
なぜTRUNCATEが早いかというと、行を1つずつ削除するのではなく、テーブルの領域そのものを初期化するからです。
条件指定の違い
DELETE(条件指定可能)
-- 特定の条件でのみ削除
DELETE FROM users WHERE age < 18;
DELETE FROM logs WHERE created_at < '2025-01-01';
DELETE FROM orders WHERE status = 'キャンセル';
TRUNCATE(条件指定不可)
-- 全件削除のみ可能
TRUNCATE TABLE users;
-- WHERE句は使えない
-- TRUNCATE TABLE users WHERE age < 18; ← これはエラー
オートインクリメントの違い
TRUNCATEの場合
-- 実行前:最大ID = 1000
TRUNCATE TABLE users;
-- 新しいデータを追加
INSERT INTO users (name, age) VALUES ('新規ユーザー', 25);
-- 追加されたデータのID = 1(リセットされる)
DELETEの場合
-- 実行前:最大ID = 1000
DELETE FROM users;
-- 新しいデータを追加
INSERT INTO users (name, age) VALUES ('新規ユーザー', 25);
-- 追加されたデータのID = 1001(継続する)
トランザクションとロールバック
DELETEの場合(ロールバック可能)
BEGIN; -- トランザクション開始
DELETE FROM test_data;
-- 「やっぱり削除したくない」となった場合
ROLLBACK; -- 削除をキャンセル(データが戻る)
TRUNCATEの場合(ロールバック不可が多い)
BEGIN; -- トランザクション開始
TRUNCATE TABLE test_data;
-- データベースによってはここで即座に反映される
ROLLBACK; -- 多くの場合、データは戻らない
TRUNCATEの注意点
条件削除はできない
TRUNCATEは「全削除」専用です。部分削除はできません。
やりたいこと:古いログだけ削除
-- これはできない
-- TRUNCATE TABLE logs WHERE created_at < '2025-01-01'; ← エラー
-- 正しくはDELETEを使う
DELETE FROM logs WHERE created_at < '2025-01-01';
外部キー制約がある場合の問題
他のテーブルから参照されているテーブルは、TRUNCATEできない場合があります。
例:注文テーブルから顧客テーブルを参照している場合
-- 顧客テーブル
CREATE TABLE customers (
id INT PRIMARY KEY,
name VARCHAR(100)
);
-- 注文テーブル(顧客IDを外部キーとして参照)
CREATE TABLE orders (
id INT PRIMARY KEY,
customer_id INT,
FOREIGN KEY (customer_id) REFERENCES customers(id)
);
-- 注文データがある状態で顧客を全削除しようとすると...
TRUNCATE TABLE customers; -- エラーになる可能性
解決方法
-- 方法1:参照する側から先に削除
TRUNCATE TABLE orders; -- 先に注文テーブルを空にする
TRUNCATE TABLE customers; -- その後で顧客テーブルを空にする
-- 方法2:DELETEを使用(外部キー制約によってはエラーになることも)
DELETE FROM customers;
ロールバックができないリスク
多くのデータベースでは、TRUNCATEは即座に反映され、取り消せません。
危険な例
-- 本番環境で間違ってTRUNCATEを実行
TRUNCATE TABLE important_data; -- データが完全に消える!
-- ロールバックしても戻らない場合が多い
安全な方法
-- まずはバックアップを取る
CREATE TABLE important_data_backup AS SELECT * FROM important_data;
-- または、まずDELETEで試す
BEGIN;
DELETE FROM important_data;
-- 問題なければCOMMIT、問題があればROLLBACK
トリガーが実行されない
DELETEトリガーが設定されていても、TRUNCATEでは実行されない場合があります。
例:削除ログを取るトリガーがある場合
-- DELETEの場合:削除ログが記録される
DELETE FROM users WHERE id = 1;
-- TRUNCATEの場合:削除ログが記録されない
TRUNCATE TABLE users;
TRUNCATEが適している場面

テスト環境でのデータリセット
-- テスト用データを全部消して、新しいテストを開始
TRUNCATE TABLE test_users;
TRUNCATE TABLE test_orders;
TRUNCATE TABLE test_products;
一時テーブルのクリア
-- 処理用の一時テーブルを空にする
TRUNCATE TABLE temp_calculations;
TRUNCATE TABLE staging_data;
ログテーブルの定期的なクリア
-- 古いログを全削除(ただし、条件削除が必要な場合はDELETEを使用)
TRUNCATE TABLE access_logs;
TRUNCATE TABLE error_logs;
大量データの高速削除
-- 数百万件のデータを高速削除
-- DELETEだと数時間かかる場合でも、TRUNCATEなら数秒
TRUNCATE TABLE large_analytics_data;
開発中のデータ初期化
-- 開発中にテーブルを何度も初期化したい場合
TRUNCATE TABLE development_data;
-- その後、初期データを再投入
INSERT INTO development_data VALUES ...;
TRUNCATEが適していない場面
部分削除が必要な場合
-- 古いデータだけ削除したい
-- TRUNCATEでは条件指定できないため、DELETEを使用
DELETE FROM logs WHERE created_at < '2025-01-01';
外部キー制約があるテーブル
-- 他のテーブルから参照されている場合はDELETEが安全
DELETE FROM customers WHERE inactive = 1;
削除履歴を残したい場合
-- 削除トリガーで履歴を残したい場合はDELETEを使用
DELETE FROM users WHERE last_login < '2024-01-01';
ロールバックが必要になる可能性がある場合
-- 慎重に削除したい場合はDELETEでトランザクションを使用
BEGIN;
DELETE FROM sensitive_data WHERE condition = 'xyz';
-- 確認後にCOMMITまたはROLLBACK
実際の業務での使用例
データ移行作業
-- 旧システムから新システムへのデータ移行
-- 1. テストデータをクリア
TRUNCATE TABLE new_users;
TRUNCATE TABLE new_orders;
-- 2. 旧システムからデータをコピー
INSERT INTO new_users SELECT * FROM old_users;
INSERT INTO new_orders SELECT * FROM old_orders;
バッチ処理
-- 日次バッチ処理での一時テーブル利用
-- 1. 前回の処理結果をクリア
TRUNCATE TABLE daily_summary_temp;
-- 2. 新しい集計データを作成
INSERT INTO daily_summary_temp
SELECT date, SUM(amount)
FROM transactions
WHERE date = CURRENT_DATE
GROUP BY date;
パフォーマンステスト
-- 性能テスト用のデータ準備
-- 1. 既存のテストデータをクリア
TRUNCATE TABLE performance_test_data;
-- 2. 大量のテストデータを作成
INSERT INTO performance_test_data (id, data)
SELECT generate_series(1, 1000000), 'test_data_' || generate_series(1, 1000000);
安全に使うためのチェックリスト

実行前の確認事項
-- ✅ 1. データの件数を確認
SELECT COUNT(*) FROM target_table;
-- ✅ 2. 重要なデータが含まれていないか確認
SELECT * FROM target_table LIMIT 10;
-- ✅ 3. 外部キー制約を確認
SELECT TABLE_NAME, CONSTRAINT_NAME
FROM information_schema.TABLE_CONSTRAINTS
WHERE CONSTRAINT_TYPE = 'FOREIGN KEY'
AND TABLE_NAME = 'target_table';
-- ✅ 4. バックアップの存在確認(重要なデータの場合)
実行時の注意
安全な実行手順
-- 1. まずは件数確認
SELECT COUNT(*) FROM users;
-- 2. 本当に削除が必要か最終確認
-- 3. 可能であればバックアップ作成
CREATE TABLE users_backup_20250603 AS SELECT * FROM users;
-- 4. TRUNCATEの実行
TRUNCATE TABLE users;
-- 5. 結果確認
SELECT COUNT(*) FROM users; -- 0件になっているはず
データベース別の特徴
MySQL
-- 外部キー制約がある場合はエラーになる
-- 一時的に制約チェックを無効にすることも可能(注意が必要)
SET FOREIGN_KEY_CHECKS = 0;
TRUNCATE TABLE referenced_table;
SET FOREIGN_KEY_CHECKS = 1;
PostgreSQL
-- RESTARTでオートインクリメントをリセット
TRUNCATE TABLE users RESTART IDENTITY;
-- CASCADEで関連テーブルも同時にクリア(危険)
TRUNCATE TABLE users CASCADE;
SQL Server
-- IDENTITYを指定してオートインクリメントをリセット
TRUNCATE TABLE users;
-- または明示的にリセット
DBCC CHECKIDENT('users', RESEED, 0);
よくあるトラブルと対処法
外部キー制約エラー
エラー例
Cannot truncate table 'users' referenced by a foreign key constraint
対処法
-- 方法1:参照する側から先に削除
TRUNCATE TABLE orders; -- 先に注文テーブル
TRUNCATE TABLE users; -- その後で顧客テーブル
-- 方法2:DELETEを使用
DELETE FROM users;
権限不足エラー
エラー例
Access denied; you need (at least one of) the DROP privilege(s)
対処法
-- 管理者に権限を依頼するか、DELETEを使用
DELETE FROM table_name;
誤削除してしまった場合
対処法
- すぐにバックアップから復旧
- バックアップがない場合はログファイルから復旧を試行
- 今後のために定期バックアップを設定
パフォーマンス比較
実際の処理時間例
100万件のデータでの比較
-- TRUNCATE:約0.1秒
TRUNCATE TABLE large_table;
-- DELETE:約30秒〜数分
DELETE FROM large_table;
メモリ使用量の違い
- TRUNCATE:最小限のメモリ使用
- DELETE:削除する行数に比例してメモリ使用
ログ容量の違い
- TRUNCATE:ログ出力が最小限
- DELETE:全ての削除がログに記録されるため容量が大きい
まとめ
SQLのTRUNCATE
文は、非常に高速で簡潔に全件削除を実現できる便利な機能です。しかし、DELETEとの違いや制限を理解して正しく使うことが何よりも重要です。
TRUNCATEの特徴
- メリット:高速、シンプル、ログ容量が少ない
- デメリット:条件指定不可、ロールバック困難、外部キー制約で制限
使い分けの指針
- 全件削除でスピード重視:TRUNCATE
- 条件付き削除や安全性重視:DELETE
- 外部キー制約がある:DELETE
- ロールバックが必要:DELETE
安全に使うためのポイント
- 実行前に必ずデータ確認とバックアップ
- 外部キー制約の有無をチェック
- テスト環境で動作確認
- 本番環境では特に慎重に
特に本番環境では「一瞬でデータが消える」ことの重大さを理解し、慎重に運用してください。
コメント