为什么 MySQL 采用 B+ 树作为索引?


前言

这个地方我们简单说一下索引的什么数据结构才是最好的,直接给出结论:1.能在尽可能少的磁盘的I/O操作中完成查询工作。2.要能高效的查询某一个记录,也要能高效地执行范围查找。


一、什么是B+树?

B+其实就是B树的升级版,B树本质上是一个二叉树,具体而言就是一个平衡二叉树。而它们也有区别。

  • B+的叶子节点(最底部的节点)才会存放实际数据(索引+记录),非叶子节点只会存放索引;
  • 所有的索引都会在叶子结点出现,叶子结点构成一个有序表;
  • 非叶子结点的索引也会同时出现在子节点中,并且是在子节点中索引的最大处或最小处;
  • 非叶子节点中有多少个子节点,就有多少个索引;

二、B+树与B树的性能比较;

1.单点查询

  • B树在查询时,由于B树里的叶子结点和非叶子结点里面存放索引又存放数据,所以有时候访问到非叶子结点可以找到数据,有时候访问到叶子结点可以找到数据,查询波动会比较大。
  • B+树的非叶子节点不存放实际的数据记录,仅存放索引,因此数据量相同的情况下,相比存储即存索引又存记录的B树,B+树可以存放更多的索引,因此B+树比B树更加矮胖,查询底层结点的磁盘I/O次数会更少。

2.插入和删除效率

由于B+树有大量的荣誉结点,这样使得删除一个结点的时候,可以直接从叶子结点删除,甚至可以不动非叶子结点,这样删除非常快。B+树在删除根结点的时候,由于存在冗余结点,所以不会发生复杂的树变形。而B树不同,B树没有冗余结点,所以删除的时候会发生复杂的树变化。插入也是一样,最多涉及树的一条路径,B+树会自动平衡,不需要更多复杂的算法。

3.范围查询

B 树和 B+ 树等值查询原理基本一致,先从根节点查找,然后对比目标数据的范围,最后递归的进入子节点查找。
因为 B+ 树所有叶子节点间还有一个链表进行连接,这种设计对范围查找非常有帮助,比如说我们想知道 12 月 1 日和 12 月 12 日之间的订单,这个时候可以先查找到 12 月 1 日所在的叶子节点,然后利用链表向右遍历,直到找到 12 月12 日的节点,这样就不需要从根节点查询了,进一步节省查询需要的时间。

总结

树的高度决定于磁盘 I/O 操作的次数,因为树是存储在磁盘中的,访问每个节点,都对应一次磁盘 I/O 操作,也就是说树的高度就等于每次查询数据时磁盘 IO 操作的次数,所以树的高度越高,就会影响查询性能。
MySQL 默认的存储引擎 InnoDB 采用的是 B+ 作为索引的数据结构,原因有:

  • B+ 树的非叶子节点不存放实际的记录数据,仅存放索引,因此数据量相同的情况下,相比存储即存索引又存记录的 B 树,B+树的非叶子节点可以存放更多的索引,因此 B+ 树可以比 B 树更「矮胖」,查询底层节点的磁盘 I/O次数会更少。
  • B+ 树有大量的冗余节点(所有非叶子节点都是冗余索引),这些冗余索引让 B+ 树在插入、删除的效率都更高,比如删除根节点的时候,不会像 B 树那样会发生复杂的树的变化;
  • B+ 树叶子节点之间用链表连接了起来,有利于范围查询,而 B 树要实现范围查询,因此只能通过树的遍历来完成范围查询,这会涉及多个节点的磁盘 I/O 操作,范围查询效率不如 B+ 树。
  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值