| 維度 | TRUNCATE TABLE | DELETE |
|---|---|---|
| 語法分類 | DDL (Data Definition Language) | DML (Data Manipulation Language) |
| 執行速度 | 極快(釋放頁、重建表結構) | 逐行刪除、記錄 Undo Log、較慢 |
| WHERE 條件 | 不支援 | 支援任意條件 |
| 觸發器 | **不觸發** DELETE 觸發器 | 觸發 BEFORE/AFTER DELETE |
| 事務/回滾 | 隱式提交,**不可回滾** | 在事務中可 ROLLBACK |
| 自增計數器 | **重置為 1**(或初始值) | 保留最大值+1 繼續 |
| 鎖粒度 | 表級元數據鎖 (MDL) + 獨佔鎖 | 行鎖 (InnoDB) / 表鎖 (MyISAM) |
| 權限需求 | DROP 權限 | DELETE 權限 |
| 外鍵約束 | **父表不可 TRUNCATE**(被引用時失敗) | 受 ON DELETE CASCADE/SET NULL 控制 |
| 空間回收 | 立即釋放磁碟空間 (InnoDB file-per-table) | 不釋放,產生碎片,需 OPTIMIZE TABLE |
| 二進制日誌 | 記錄為單條 DDL 事件 | 記錄每行刪除 (ROW 格式) |
TRUNCATE TABLE friends;
-- 等同
TRUNCATE friends;
-- 單表條件刪除
DELETE FROM somelog
WHERE user = 'jcole'
ORDER BY timestamp_column
LIMIT 1;
-- 多表刪除 (內連接語法)
DELETE t1, t2
FROM t1
INNER JOIN t2 ON t1.id = t2.id
INNER JOIN t3 ON t2.id = t3.id;
-- 多表刪除 (USING 語法)
DELETE FROM t1, t2
USING t1, t2, t3
WHERE t1.id = t2.id AND t2.id = t3.id;
TRUNCATE。DELETE。DELETE ... LIMIT 1000 + usleep 休眠,避免長鎖表、Replication 延遲、Undo Log 膨脹。while (true) {
$affected = $pdo->exec("DELETE FROM logs WHERE log_date <= '2009-11-01' LIMIT 1000");
if ($affected == 0) break;
usleep(50000); // 50ms 緩衝
}
TRUNCATE 是「重建表」的核彈級操作,極快但不可逆;DELETE 是精準手術刀,支援條件、事務、觸發器。根據業務需求選擇,大量刪除務必分批。