你真的知道MySQL索引为什么使用B+树吗?看一篇文章满满干货!


前言

一提到MySQL索引,大家自然而然就会想起一种非常经典的数据结构B+树。网上有大量的资料介绍B+树,但大多都是介绍B+树的建立规则以及各种计算公式,看着十分头疼。本篇文章就来简单的探讨MySQL索引使用B+树的原因。


1、MySQL索引为什么不使用其他数据结构?

1.1 二叉搜索树

如果单从查找逻辑上讲,二叉搜索树的查找速度非常快。但是这是基于所有的数据都是在内存中查找的情况下。

现在我们要面对现实一个问题:磁盘读写速度。
众所周知数据库索引是存储在磁盘上的(以磁盘页形式存储),如果数据量不大可以全部装载到内存中,如果数据量太大则无法将全部索引一次性加载到内存,只能逐一加载磁盘页(对应着搜索树的节点)。

在下面这个二叉搜索树中,我们如果要查找8这个节点,要经过9->5>7>8,这个过程对磁盘整整读写了四次,跟树的高度一样(这是最差的情况)。如果树的高度很高,就可能进行很多次磁盘读写,这是我们无法接受的!
在这里插入图片描述
那么解决办法是什么呢?答案很明显,降低树的高度,通俗的话来说就是把高瘦的树变成矮胖的树,磁盘IO次数就能减少。

1.2 B树

我们先来看看B树。B树是多路平衡树的一种,B树的定义如下:

1.B树每个节点元素数量和子树数量有限,k是B树的阶,除了根节点其他节点最多拥有k-1个元素,非叶子非根节点最多拥有k个子树。
2.所有叶子节点属于同一层。

下面这图就是一个三阶B树(也可以叫三路B树)。设计成多阶的原因是进一步降低树的高度,阶越多树的高度越低。
在这里插入图片描述
如果我们要查找3,首先先找到9,然后找到2和6(保存在一个节点上),然后找到3和5(保存在一个节点上),这样也就找到了3,需要对磁盘读写3次,比上面的二叉搜索树少了一次磁盘读写。

以上的例子只是大家帮助理解,现实中磁盘的读写非常昂贵,现实中程序可能对磁盘进行成千上万次读写,这时候使用B树将会大幅度提升性能,由于一个节点存储数据量比较大,一般现实中整个索引树层数非常低(呈现矮胖的形态)。

接下来我们来看一下使用B树作为MySQL索引存储的数据结构的示例图。
在这里插入图片描述
B树虽有很多好处,但仍存在很多问题。
1.每个节点中有key,也有data,但是每一个节点(磁盘页)的存储空间是有限的,如果data数据较大时会导致每个节点能存储的key的数据很小,最后导致B树的高度较大,磁盘IO次数增多。

2.索引和内容分散在整个B+树上,离根节点近搜索快,离根节点远搜索慢,花费的IO时间不平均。

3.树不方便做范围搜索,例如要查找大于3小于10的数据,则需要先达到磁盘块5找到3,然后回到磁盘块2比较,在到磁盘块6找到9,这相当于进行了局部的中序遍历,情况更糟的情况下可能还要跨层访问。

1.3 红黑树和哈希表

可能有读者问为什么不使用红黑树或者哈希表?首先我们来看一下红黑树。
我们要学习一个数据结构之前必须要知道这个数据结构解决的是什么问题。上面1.1的二分搜索树还算比较正常,接下来我来看一颗畸形的二叉搜索树。
在这里插入图片描述
如果数据是单边增长的情况 那么出现的就是和链表一样的数据结构,树高度大。
而红黑树的诞生就是为了解决这个问题,在二分搜索树的基础上多了树平衡,也叫平衡二叉树,不像二分搜索树那样极端的情况会往一个方向发展。
在这里插入图片描述
简单来说:红黑树出现是为了解决二分搜索树单侧增长的问题,不是为了数据库索引而诞生的,B树和B+树克服了红黑树克服不了的困难,因为随着数据量增多,红黑树的高度必然也会变得很高,造成磁盘io次数的增加。

而对于哈希表,如果只是查找一条数据那确实效率很快(进行一次哈希运算即可),但我们需要考虑查询多条数据的情况,提问B+树索引有序,加上B+树有链表相连,这时候效率就比hash高。


2、B+树为什么能成为天选之子

前面铺垫了这么多,现在终于要介绍本篇文章的主角:B+树。
接下来我们来看一下使用B+树作为MySQL索引存储的数据结构的示例图。所有数据保存在叶子节点上,叶子节点有链表相连。
在这里插入图片描述
1.跟B树相比,B+树的叶子结点是一条链表,会将搜有的数据连接在一起,做整表遍历和区间查找是非常容易的,例如查找3到15范围内的数据,通过链表就能把所有数据取出来了(即磁盘块4和磁盘块5是相连的)。

2.每个非叶子节点只存放key值,这样一个节点就能存放更多的key值,从而降低树的层高。

3.B+树所有的数据都存在叶子节点上,找到对应数据的时间比较平均的。

综上所述,Mysql最后采用B+树作为索引而没有采用B树。


总结

本篇文章主要介绍两部分内容,第一部分讲解为什么其他的结构不适合作为索引的存储结构,第二部分讲解将B+为什么能成为MySQL索引存储结构的天选之子。全篇的关键就在于实际中我们需要考虑磁盘io因素,减少磁盘io次数将会大幅度提高系统性能。建议读者不要太去纠结B树和B+树的一些计算公式,学习数据结构一定要想到它的使用场景,这样才能在以后被我们使用。


  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JinziH Never Give Up

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值