萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 資料庫 >> MySQL 教學

MySQL TRUNCATE 與 DELETE 差異深度解析

核心差異速查表

維度TRUNCATE TABLEDELETE
語法分類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

TRUNCATE TABLE friends;
-- 等同
TRUNCATE friends;

DELETE

-- 單表條件刪除
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;

選擇指引

  1. 清空整張表、重置自增 ID、不需觸發器、可接受不可回滾 → TRUNCATE。
  2. 保留部分資料、需觸發器、需事務回滾、父表被引用 → DELETE。
  3. 大量刪除(百萬級):分批 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 是精準手術刀,支援條件、事務、觸發器。根據業務需求選擇,大量刪除務必分批。

copyright © 萬盛學電腦網 all rights reserved