TRUNCATE 比 DELETE 快得多,因其是 DDL 操作,直接重建表结构、清空数据页并重置自增计数器,不写事务日志;而 DELETE 是 DML,逐行记录 undo log 和 binlog,还触发约束与触发器。
Truncate 为什么比 Delete 快得多
因为
是 DDL 操作,直接重建表结构(清空数据页、重置自增计数器),不走事务日志逐行记录;而
是 DML 操作,每删一行都写入 undo log 和 binlog(若开启),还要触发触发器、检查外键约束——千万级下
可能跑几小时甚至锁表失败。
Truncate 能用的前提条件
必须满足全部以下条件,否则会报错或行为异常:
不支持带
条件,只能清空整表
不能在有外键引用的子表上执行(MySQL 会直接拒绝,报错
)
不能用于临时表(
)或分区表的单个分区(要用
)
执行用户需具备
权限(不是
权限)
替代 Delete 的安全清理方案(当 Truncate 不能用时)
如果表被其他表外键引用,或只需删旧数据(比如保留最近 3 个月),
就不可用。此时应分批
+ 主键范围控制:
MySQL(Linux)
MySQL 9.6.0是面向Linux平台的2026年创新版本,核心架构迎来重大革新。其将外键约束与级联操作从InnoDB引擎层上移至SQL层,确保所有数据变更均被完整记录至Binlog,彻底解决了CDC(变更数据捕获)与主从复制中的数据不一致难题。此外,该版本引入container_aware启动选项以原生适配容器环境,并对审计日志进行了组件化重构,为追求极致数据一致性与云原生体验的开发者提供了全新选择。
下载
反复执行直到无匹配行。关键点:
必须用主键或有索引的字段做范围条件,避免全表扫描
每次
建议 5k–10k 行,太大易锁表,太小增加 round-trip 开销
执行前关掉 autocommit,手动
每批,防止事务日志暴涨
注意
下,大事务仍可能打爆磁盘,建议搭配
避免从库延迟
Truncate 后的隐性代价别忽略
快是有代价的:
会重置
计数器为 1(除非表定义了
),且无法回滚(即使在事务里执行也会立即提交)。更隐蔽的是:如果表上有
索引,
后首次插入会触发全文索引重建,可能卡住后续写入;另外,某些监控系统依赖表的
变化来告警,
后该值归零,可能触发误报。
TRUNCATEDELETEDELETETRUNCATEWHEREERROR 1701 (HY000)TEMPORARY TABLEALTER TABLE ... TRUNCATE PARTITIONDROPDELETETRUNCATEDELETEDELETE FROM orders WHERE id < 1000000 LIMIT 10000;LIMITCOMMITbinlog_format=ROW--slave-parallel-type=LOGICAL_CLOCKTRUNCATEAUTO_INCREMENTauto_increment_offsetFULLTEXTTRUNCATEDATA_LENGTHTRUNCATE