delete可回滚且支持where条件删除,truncate不可回滚且只能清空整表。

想安全又高效地删数据,关键不是“怎么删”,而是“为什么删”和“删完能不能补救”。DELETE 和 TRUNCATE 表面都清空数据,但底层逻辑、适用场景和风险等级完全不同。
能不能撤回?这是第一道红线
DELETE 是事务型操作,删完不提交(COMMIT),随时可以用 ROLLBACK 撤销。哪怕刚删了几百万行,只要没 COMMIT,数据还在回滚段里,能原样恢复。TRUNCATE 属于 DDL 操作,一执行就自动提交,不可回滚。删完就真没了,没有“后悔键”。
能不能挑着删?看是否需要 WHERE 条件
DELETE 支持完整的 WHERE 子句,可以精准删除满足条件的行,比如:
DELETE FROM orders WHERE status = 'cancelled' AND created_at
TRUNCATE 不接受任何条件,只能整表清空。它没有 WHERE,也不允许 JOIN 或子查询。想留几条数据?TRUNCATE 做不到。
删完表还“像不像原来那个”?关注自增和触发器
- 自增主键(如 MySQL 的 AUTO_INCREMENT):TRUNCATE 会重置为初始值(通常是 1);DELETE 即使删光所有行,下次插入仍从原最大值 +1 开始。
- 触发器(Trigger):DELETE 会逐行触发 DELETE 类型的触发器;TRUNCATE 完全不触发任何触发器,适合跳过业务逻辑快速清空。
- 高水位线(HWM):TRUNCATE 会复位 HWM,释放存储空间;DELETE 只标记数据为删除,空间不释放,表文件大小不变。
什么时候该用哪个?一句话判断
- 要删一部分数据 → 只能用 DELETE,必须带 WHERE
- 要删全部数据,且确定不需要回滚、不依赖触发器、希望重置自增 → 优先用 TRUNCATE
- 要删全部数据,但需触发器响应、或可能回滚、或不能重置自增 → 只能用 DELETE(无 WHERE)
- 连表结构一起不要了 → 用 DROP,不是 DELETE 或 TRUNCATE 的事










