DELETE 和 TRUNCATE TABLE区别

例子:我想删掉数据,但是这个数据有唯一键,怎么删能把唯一索引也给删了

总结

  • 是否会删除索引
    • 都会删除索引,只是删除的方式不一样

这是一个非常深刻且直击 MySQL 底层架构的核心问题!

直接回答你的问题:都会清理掉索引,但 DELETETRUNCATE 清理的"动作"和"彻底程度"有着天壤之别!

为了让你彻底弄懂,我们必须掀开 MySQL InnoDB 引擎的底裤,看看 B+ 树索引在增删改时到底发生了什么。


1. DELETE:小心翼翼地"擦除",但留下"空洞"(逻辑删除 + 碎片)

当你执行 DELETE FROM table WHERE sid = 111 时,MySQL 的动作是非常轻量且局部的:

  1. 数据页:InnoDB 其实并不会立即把这行数据从磁盘上物理抹掉,而是给这行数据打上一个**"删除标记"**(这就是所谓的逻辑删除),并在记录头维护一个"已删除链表"。
  2. 索引页(B+ 树) :InnoDB 会定位到唯一索引 B+ 树中 sid = 111 的那个节点,把这个节点的标记改为"已删除"

关键点来了:

  • 索引条目被清理了吗? 是的,逻辑上被清理了。此时如果你再插 sid = 111,B+ 树遍历时发现原来的 111 已经标记为删除,所以不会报唯一键冲突,可以正常插入。
  • 物理空间被释放了吗? 没有! 那个被标记删除的节点,依然占据着 B+ 树的物理空间(索引页的空洞)。
  • 后果 :如果你频繁地 DELETEINSERT,B+ 树里会充满这种"空洞",导致索引树变得非常臃肿(索引碎片),查询时需要读取更多的磁盘页,性能急剧下降。这也是为什么大表经常需要执行 OPTIMIZE TABLE 或重建索引来回收空间。

2. TRUNCATE:暴力拆迁,原地建新城(物理销毁)

当你执行 TRUNCATE TABLE 时,MySQL 根本不屑于去挨个标记删除节点,它的动作是毁灭性的:

  1. 丢弃旧表空间 :InnoDB 直接把这张表对应的数据文件(.ibd 文件)和所有的索引 B+ 树,从磁盘上彻底删除、物理销毁
  2. 创建新表空间:然后,重新分配一片干净的磁盘空间,初始化一个全新的、空空如也的数据文件和索引 B+ 树。

关键点:

  • 索引条目被清理了吗? 连整棵树都被连根拔起了,根本不存在什么条目了。
  • 物理空间被释放了吗? 完全释放! 磁盘空间瞬间归还给操作系统,新表占用的空间极小。
  • 后果 :极致的快,极致的干净。没有任何历史包袱,没有碎片。插入 sid = 111 就像在白纸上写字一样丝滑。

📝 通俗总结

回到你的问题:删除数据时,索引会被清理吗?

  • DELETE :索引条目会被逻辑清理 (打上删除标记,不再阻挡新数据插入),但物理空间不释放(留下空洞碎片)。
  • TRUNCATE :索引会被物理清理(整棵索引树被炸毁重建),干干净净,恍如初见。

专家附加提示:

这也是为什么在分库分表的环境下,如果你要清空一张表的数据,只要你不心疼表里的其他数据,永远优先使用 TRUNCATE ,而不是 DELETE。因为 TRUNCATE 不会产生大量的 Binlog(二进制日志),不会导致主从延迟,也不会留下索引碎片!

相关推荐
用户446139430271 分钟前
从单体到微服务:我们项目的拆分思路和踩坑记录
java
X-⃢_⃢-X10 分钟前
十、Redis之布隆过滤器
数据库·redis·缓存
Nturmoils13 分钟前
订单号查出了三笔,我以为是数据脏了,其实是自己写错了
数据库
ZKNOW甄知科技17 分钟前
燕千云深度集成飞书:以AI之力,开启无感IT运维体验
大数据·运维·网络·数据库·人工智能·低代码·集成学习
TDengine (老段)31 分钟前
TDengine 免费版说明
java·大数据·数据库·物联网·时序数据库·tdengine
汉知宝科技32 分钟前
历史案件数据迁移:知识产权管理系统落地的第一道门槛
大数据·数据库
码上有光35 分钟前
异常和智能指针
java·大数据·c++·servlet·异常·智能指针
这就是佬们吗42 分钟前
Python入门⑤-异常处理、文件操作与实战项目
开发语言·数据库·python·算法·pycharm
吴声子夜歌43 分钟前
MongoDB 4.x——SpringBoot框架整合
数据库·spring boot·mongodb
凤山老林1 小时前
MySQL“读已提交“并非万能药:深度解析RC隔离级别的盲区与适用边界
数据库·mysql