首页/数据/数据库速查/DELETE 与 TRUNCATE 删除数据
SQL 语法52 条

DELETE 与 TRUNCATE 删除数据

DELETE 可带条件、逐行记录 binlog(可回滚);TRUNCATE 直接重建表、不可回滚、秒级清空整表并重置自增。

数据库速查数据更新于 2026-10-13

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,否则删除顺序不确定、分批边界会漂移;每批之间留出短暂停顿,能给从库回放和主库刷脏页留出喘息空间。

易错点

  • 一条 DELETE 删几千万行,长事务把 undo 与主从延迟同时拖爆
  • TRUNCATE 后自增从 1 重新开始,若业务依赖旧 id 会造成主键冲突或数据错位
  • DELETE 未加 WHERE 直接清空生产表,只能靠备份恢复
  • 以为 TRUNCATE 会触发触发器,业务侧审计与清理逻辑没有执行
  • 把 TRUNCATE 当作可回滚操作放在事务里,结果被隐式提交后无法撤销

数据来源与参考

  • MySQL 8.0 Reference Manual: TRUNCATE TABLE Statement

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌