MySQL索引底层结构为什么用B+Tree?

索引为何不选择二叉树?

二叉搜索树是遵守二分搜索法实现的一种数据结构,它具有下面特点:

  • 任意节点的左节点不为空时,左节点值小于根节点值;
  • 右节点不为空时,右节点值大于根节点值;

依次存入数据,如果数据是递增的,则原二叉树退化为链表结构

 从动画中可以明显看到,需要经过 5 次查询才能找到目标数据,由于树结构在磁盘中存储的位置也不连续,所以最终需要发生 5 次磁盘 IO 才能找到目标数据。

二叉树不适合作为索引结构的原因:

  • ① 如果索引的字段值是按顺序增长的,二叉树会转变为链表结构,因此检索的过程和全表扫描无异。
  • ② 每个节点中只存储一个数据,节点之间还是不连续的,每次磁盘 IO 只能读取一个数据。

索引为何不选择红黑树?

相比于二叉树,红黑树则进一步做了优化,它是一种自适应的平衡树,会根据插入的节点数量以及节点信息,自动调整树结构来维持平衡。

由于树变矮了,其效果也很明显,而红黑树中只需要经过 3 次 IO 就可以找到目标数据,似乎看起来还不错对嘛?但 MySQL 为啥不用这颗名声远扬的红黑树呢?

红黑树不适合作为索引结构的原因:

  • ① 虽然对比二叉树来说,树高有所降低,但数据量一大时,依旧会有很大的高度。
  • ② 每个节点中只存储一个数据,节点之间还是不连续的,每次磁盘 IO 只能读取一个数据。

索引为何不选择 B-Tree?

B 树和红黑树相比,其单节点可容纳多个数据,就能在很大程度上改善其性能,使 B 树的树高远远小于红黑树的高度。

 

对比红黑树可以发现,每个节点上可以存储更多的数据,且树高固定,数据插入之后横向扩展。观察动画只需要 2 次 IO 就可以找到目标数据,搜索效率大大提高了。并且每个节点的元素我们可以自己空值。

那么为什么 MySQL 没有采用 B 树结构了?

我们仔细观察可以知道 B 树的叶子节点直接是没有指针的,但是日常查询中包含了大量的范围查找,所以当出现范围查找的时候,会出现多次的 IO 查找。

B 树不适合作为索引结构的原因:

  • ① 虽然对比之前的红黑树更矮,检索数据更快,但对于大范围查询的需求,依旧需要通过多次磁盘 IO 来检索数据。

索引为何要选择 B+Tree?

B+树是在 B 树的基础进一步优化,一方面节点分为了叶节点和叶子节点两类,另一方面叶子节点之间存在单向链表指针。

B+树相比于 B 树叶子节点之间多了个单项指针,当需要做范围查询时,只需要定位第一个节点,然后就可以直接根据各节点之间的指针,获取到对应范围之内的所有节点,也就是只需要发生一次 IO,就能够确定所查范围之内的所有数据位置。

其实 MySQL 底层真正的索引结构还对叶子节点之间的指针进行了优化,B+树叶子节点的单向指针无法友好支持的倒叙查询,因此 MySQL 针对单项指针优化成了双向指针,也就是双向链表结构。即可以快速按正序进行单位查询,而可以快速按倒序进行范围查询,在某些业务场景下又能进一步提升整体性能!

这里在总结一下B树和B+树:

共同特性:小的索引在左边,大的索引在右边。

区别:

B树每一个节点都存储了索引和数据。

而 B+树它把所有的数据都放在了最下面的叶子节点,而非叶子节点只存储索引。这样就可以留出更多的空间,去存储更多的索引,从而可以组织一颗更宽的一颗 B+树,树更宽的话,是不是进行 i/o 的数据检索次数就更少了,进而查询效率就更快。

第二点区别: B+树它通过双向链表去连接了每一个叶子节点,那么这样的话就会让他的范围查询的性能就会更好。

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值