SQL 如何用 TRUNCATE 代替 DELETE 在大表清空时的性能提升-SQL

TRUNCATE比DELETE快的根本原因是其为DDL操作,直接释放数据页或段,不逐行扫描、不记录单行日志、不触发触发器;而DELETE是DML,需逐行处理日志、索引、约束等冗余开销。

TRUNCATE 比 DELETE 快的根本原因

TRUNCATE 是 DDL 操作,直接释放数据页(page)或段(segment),不逐行扫描、不记录单行 DELETE 日志,也不触发触发器。而 DELETE 是 DML,会为每一行生成日志、维护索引、检查外键约束、可能触发 ON DELETE 行为——这些在清空整表时全是冗余开销。

  • TRUNCATE 通常只写一条事务日志(如 SQL Server 的 LOP_TRUNCATE_PAGE,PostgreSQL 的 RELATION TRUNCATE)
  • 不锁全表?错:多数数据库仍需获取排他锁(X lock),但持有时间极短
  • 不走事务日志重做?不完全对:它仍记日志,只是粒度粗、量极少;InnoDB 中 TRUNCATE 本质是 DROP + CREATE,会重建聚簇索引

哪些情况不能用 TRUNCATE 替代 DELETE

TRUNCATE 看似万能,但实际限制比想象中多:

  • 表被其他表通过外键(FOREIGN KEY)引用(MySQL 8.0+ 支持级联截断,但需显式声明 ON DELETE CASCADE,且 TRUNCATE 本身不触发该行为)
  • 当前会话正持有该表的未提交事务(如已 SELECT ... FOR UPDATE)
  • 使用了复制(replication)且 binlog 格式为 STATEMENT:MySQL 中 TRUNCATE 在该模式下不可见于从库(5.7+ 默认改用 MIXED 或 ROW 后才安全)
  • 需要条件清空(比如只删 status = 'archived' 的行)→ 只能用 DELETE 或分区表 DROP PARTITION
  • 表上有启用的触发器(TRUNCATE 绝对不触发任何 BEFORE/AFTER DELETE)

不同数据库中 TRUNCATE 的关键行为差异

行为不一致是线上翻车高发区,尤其跨数据库迁移时:

夏夕资源网专注于CMS网站模板,主流语言整站网站源码下载,网站建设相关教程分享,好用的软件素材整合下载,提供一站式便捷自助服务。
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,默认解压密码为"zy.lucklyus.top",如遇到无法解压的请联系管理员!
夏夕资源网-网站模板_免费源码_资源素材 » SQL 如何用 TRUNCATE 代替 DELETE 在大表清空时的性能提升-SQL
在线时间:12:00 - 22:00
关注微信公众号:微信公众号
站长邮箱:[email protected]
  • 运营天数: 1393+
  • 资源总数: 47989+
  • 用户总数: 1+
  • 今日更新: 0+
  • 访问次数: 4025419+
  • 本周更新: 0+
  • 最后更新: 2026-03-16

本站指数

×
  • 运营天数: 1393+
  • 资源总数: 47989+
  • 用户总数: 1+
  • 今日更新: 0+
  • 访问次数: 4025419+
  • 本周更新: 0+
  • 最后更新: 2026-03-16