DELETE 与 TRUNCATE 是什么
DELETE 按条件逐行删除,可以放在事务里回滚,ROW 格式下会把删除的行写进 binlog,代价是产生大量 undo 并可能形成长事务;TRUNCATE 直接重建表,属于 DDL,隐式提交且不可回滚,能秒级清空整表、重置自增计数器,但不会触发触发器。
基本信息
| 适用版本 | MySQL 5.7 / 8.0;分区表可用 DROP PARTITION 替代大批量删除 |
|---|---|
| DELETE 特性 | 可带 WHERE、可回滚、触发触发器、写 binlog |
| TRUNCATE 特性 | DDL、隐式提交、不可回滚、重置 AUTO_INCREMENT |
| 恢复手段 | DELETE 可从 binlog 恢复;TRUNCATE 只能靠备份 |
| 权限差异 | TRUNCATE 需要 DROP 权限,DELETE 只需该表 DELETE 权限 |
典型使用场景
- 历史数据清理:按时间条件分批删除,控制单批耗时
- 清空导入临时表:TRUNCATE 比重建表更快且自增归零
- 分区表清理:直接 DROP PARTITION,避免逐行删除
- 误删恢复:DELETE 场景可用 binlog 或备份做定点恢复
- 测试环境重置:清空数据并让自增从 1 开始
- 核对影响行数:删除前先跑同条件 SELECT COUNT 评估规模
用法对比与分批删除
用法对比与分批删除
DELETE FROM logs WHERE created_at < '2026-01-01' LIMIT 5000; -- 分批删除
TRUNCATE TABLE staging_import; -- 秒级清空整表
-- 分批循环,每批提交一次,避免长事务
DELETE FROM logs WHERE created_at < '2026-01-01' ORDER BY id LIMIT 5000;
-- SELECT ROW_COUNT(); -- 每批后确认影响行数,为 0 表示删完
-- 分区表的更优做法:
ALTER TABLE logs DROP PARTITION p202601;
SHOW CREATE TABLE logs; -- 核对分区定义与自增起始值三种清理方式对照
| 方式 | 可否回滚 | 适用规模 |
|---|---|---|
| DELETE 带 WHERE | 可以,可写 binlog 恢复 | 按条件清理,需分批控制 |
| TRUNCATE | 不可以,属 DDL | 整表清空,秒级完成 |
| DROP PARTITION | 不可回滚,但只影响单个分区 | 分区表按时间批量清理 |
| CREATE 新表加 RENAME | 可保留原表做回退 | 超大表结构或数据整理 |
TRUNCATE 是 DDL 语义:隐式提交事务、不能回滚、会重置 AUTO_INCREMENT。
不带 WHERE 的 DELETE 或误用 TRUNCATE 在生产上是不可逆事故:执行前先确认库名表名、用 SELECT COUNT 估算行数,并在低峰期操作,重要表先做备份。
带 LIMIT 的 DELETE 应同时带 ORDER BY,否则删除顺序不确定、分批边界会漂移;每批之间留出短暂停顿,能给从库回放和主库刷脏页留出喘息空间。