はじめに
オブジェクティブグループの@bachiuekiです!
弊社では月に1回、社内講習会を開いておりまして自分はSQL講習を担当しております。
今回はテーブルのデータを削除するDELETE文とTRUNCATE文についてのお話です。
データベースの運用中、「テーブルのデータを空にしたい」という場面がよくあります。
その際、DELETEとTRUNCATEのどちらを使うべきか迷ったことはありませんか?
どちらも「全データを消す」という点では同じに見えますが、内部的な動作や挙動には大きな違いがあります。
本記事では、両者の違いをわかりやすく整理します。
基本構文
-- DELETE(条件なし)
DELETE FROM テーブル名;
-- TRUNCATE
TRUNCATE TABLE テーブル名;
分類の違い
まず前提として、2つはSQLの分類が異なります。
| 文 | 分類 | 正式名称 |
|---|---|---|
| DELETE | DML | データ操作言語(Data Manipulation Language) |
| TRUNCATE | DDL | データ定義言語(Data Definition Language) |
DDLはテーブルそのもの、DMLはテーブルの中身を操作する言語というイメージですね。
この分類の違いが、以降で説明するさまざまな挙動の差につながっています。
違いの比較表
| 項目 | DELETE | TRUNCATE |
|---|---|---|
| WHERE句による条件指定 | 可能 | 不可 |
| ロールバック | 可能 | 基本的に不可※ |
| トリガーの発火 | する | しない |
| 処理速度 | 遅い | 速い |
| AUTO_INCREMENTのリセット | されない | される |
| ログ記録 | 行ごとに記録 | 最小限 |
※ PostgreSQLではTRUNCATEもトランザクション内でロールバック可能です。
詳しい違い
1. 処理速度
DELETEは1行ずつ削除してトランザクションログに記録するため、大量データでは時間がかかります。
一方TRUNCATEは、行単位ではなくデータページごと領域を解放するため、レコード数によらず高速です。
数百万件のデータを削除する場合、DELETEでは数分かかる処理がTRUNCATEなら一瞬で終わる、といったケースもあります。
余談ですがAIに聞いてみると「掃除機で丁寧に掃除する」か、「家の中をブルドーザーでまとめて更地にするか」の違いです!って言ってました。家の中を!?
2. ロールバック(トランザクション)
DELETEはDMLなので、トランザクション内で実行すればROLLBACKで取り消せます。
BEGIN;
DELETE FROM users;
ROLLBACK; -- データが元に戻る
TRUNCATEはDDLのため、多くのDBMSで自動コミットが走り、ロールバックできません。
BEGIN;
TRUNCATE TABLE users;
ROLLBACK; -- 元に戻らない
PostgreSQLは例外で、TRUNCATEもトランザクション内でROLLBACKできます。
使用しているDBMSの仕様を確認しましょう。
3. トリガーの発火
DELETEではBEFORE DELETE / AFTER DELETEトリガーが行ごとに発火します。
TRUNCATEではトリガーが発火しません。削除に連動して別テーブルを更新するような処理を組んでいる場合は注意が必要です。
4. AUTO_INCREMENTのリセット
-- DELETEの場合:連番は続きから始まる
DELETE FROM users;
INSERT INTO users (name) VALUES ('yamada');
-- → IDは 101(削除前の最大IDの続き)
-- TRUNCATEの場合:連番が1にリセットされる
TRUNCATE TABLE users;
INSERT INTO users (name) VALUES ('yamada');
-- → IDは 1
テスト環境などでIDを初期状態に戻したい場合はTRUNCATEが便利です。
どちらを使うべきか?
| シーン | おすすめ |
|---|---|
| 条件を絞って削除したい | DELETE |
| 間違えたときに取り消したい | DELETE |
| 削除に連動してトリガーを動かしたい | DELETE |
| 大量データをまるごと高速に消したい | TRUNCATE |
| 開発・テスト環境のデータをリセットしたい | TRUNCATE |
| AUTO_INCREMENTも一緒にリセットしたい | TRUNCATE |
まとめ
-
DELETEは柔軟性重視。条件指定・ロールバック・トリガー連動が必要な場面で使う -
TRUNCATEは速度重視。テーブルを丸ごとリセットしたいときに使う - ロールバックの可否はDBMSによって異なるので、環境に応じて確認する
「全件削除ならどちらでも同じ」と思いがちですが、用途と状況に応じて使い分けることが大切です。
オブジェクティブグループではXの投稿も平日毎日行っています!
IT 関連の小ネタや便利技から、日常のアニメ・ゲーム布教なども幅広く投稿してるので、
ご興味のある方は是非フォロー・いいねをお願いします。