MySQL 提供 DELETE、TRUNCATE、DROP 三種刪除方式,在事務安全、空間回收、高水位線、觸發器觸發、自增重置等維度差異巨大。本文全維度對比,給出場景選型建議。
-- DELETE:可帶條件、排序、限制行數
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM tbl_name
[WHERE where_condition]
[ORDER BY ...]
[LIMIT row_count];
-- TRUNCATE:僅整表清空,DDL 性質
TRUNCATE [TABLE] tbl_name;
-- DROP:刪除表結構及數據
DROP TABLE [IF EXISTS] tbl_name;
| 維度 | DELETE (無 WHERE) | TRUNCATE | DROP |
|---|---|---|---|
| 語句類型 | DML | DDL | DDL |
| 事務安全 | ✅ 支持回滾(在事務中) | ❌ 隱式提交,**不可回滾** | ❌ 隱式提交,**不可回滾** |
| 觸發器 | ✅ 觸發 FOR EACH ROW 觸發器 | ❌ 不觸發 | ❌ 不觸發 |
| 空間回收 | ❌ 不回收(高水位線不變),InnoDB 標記可重用 | ✅ 釋放到 MIN_EXTENTS(可 REUSE STORAGE 保留) | ✅ 完全釋放(含 .frm/.ibd/.MYD/.MYI) |
| 高水位線 | 保持原位 | 重置為 0 | 表不存在 |
| 自增計數器 | 保持最大值+1 | 重置為 1 | 表不存在 |
| 執行速度 | 慢(逐行刪除、生成 Undo/Redo) | 極快(Drop+重建表) | 極快 |
| 鎖類型 | 行鎖(InnoDB) | 表級排他鎖(元數據鎖) | 表級排他鎖 |
| 外鍵約束 | 檢查並報錯/級聯 | **被引用表不可 TRUNCATE**(需先刪外鍵) | 被引用表不可 DROP(需先刪外鍵) |
| 權限需求 | DELETE 權限 | DROP 權限(實為 DROP+CREATE) | DROP 權限 |
DELETE WHERE ...(必帶 WHERE,小心不帶 WHERE 全表刪)TRUNCATE TABLE(秒級完成)DELETE FROM tbl(慢但安全)DROP TABLETRUNCATE TABLE ... REUSE STORAGE(保留空間)+ 重新導入數據ERROR 1701 (42000): Cannot truncate a table referenced in a foreign key constraint → 先 ALTER TABLE child DROP FOREIGN KEY fk_name 再 TRUNCATE 再加回外鍵。-- 避免長事務、鎖升級、Undo 日誌暴漲
DELETE FROM huge_table WHERE create_time < '2023-01-01' LIMIT 10000;
-- 循環執行直到 affected_rows = 0
mysqlbinlog 定點恢復(ROW 格式下可行)。要刪幾行用 DELETE,帶上 WHERE 別手抖;
全表清空要快用 TRUNCATE,事務觸發器外鍵先思維;
結構數據全不要,DROP TABLE 一鍵了;
誤操作無後悔藥,備份演練要常抓。
根據業務對事務、觸發器、外鍵、空間回收、自增重置的具體要求,在三者中精準選型,避免「用 TRUNCATE 卻要回滾」或「用 DELETE 清空億級表」的災難。