跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

MySQL如何快速清理千万级的数据表_使用Truncate而非Delete

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

相关文章