如何理解mysql的索引为何要使用B+树来实现

如何理解mysql的索引为何要使用B+树的数据结构

​ 我们知道在mysql中,给一个字段加上索引之后,查询速度会快很多。为何会快很多,是因为在给一个字段加上索引之后,会根据这个字段生成对应的一个树,然后在树中进行查找时,我们的复杂度就从O(n)变成了O(log(n)),当我们的表越大时,树的查找速度相比于原来的遍历查找就会快很多。

​ 关于这个树为什么是B+树,为什么不是二叉树,B树,或者其它树。我们可以做出以下分析:

​ 首先是二叉树,但二叉树在面对原序列有序时会发生不平衡的现象,退化成单链表,如下图所示:

在这里插入图片描述

​ 此时这个二叉树的高度接近于n,那么查询的复杂度也接近于O(n),在数据库中还是很容易遇到这种情况的,所以不适用与我们的索引结构,但我们能看到上述的问题主要是由于树的高度造成的,所以我们可以尝试使用二叉平衡树(AVL),如图所示:
在这里插入图片描述

​ 在面对上面二叉树遇到的情况时,AVL能够动态的去平衡二叉树,且左右子树的高度相差不会超过1,所以我们的查询的复杂度此时是O(log(n))的,那么为何没有选择用这种树呢?

​ 假设我们现在有一千多万的数据,根据log(n)可得,大概需要查找24次就能查找到我们的数据,你看我们从千万级优化到了24次。然后补充一点就是,我们这一千多万数据是存在磁盘上的,我们在做查询的时候需要从磁盘中读到内存中进行处理,也就是说,我们每对树向下进行一次查找,就会进行一次磁盘io。所以我们在这个二叉树上进行查询时的操作,绝大部分都需要进行20次磁盘io以上;在当时的年代硬盘采用的还只是机械硬盘,机械硬盘相比于内存的速度可是慢了好几个数量级,所以优化查询的速度自然想到了减少io次数,在内存里面做更多的操作,因为内存就是比硬盘快。

​ 所以我们想到了B树,B树相比于二叉树,每个节点上我们能够存储更多的索引,我们树的高度也会因此变矮,如图所示:

在这里插入图片描述

可以看到在这个度为3的b树上,树的高度为3 (当这个度的值越大时,B树的高度也会更矮),如果这些数据转换为AVL,那么树的高度为5,所以我们的磁盘IO是明显变少了。

但是mysql采用的其实是B树,而不是B+树,那B+树相比于B树有何不同?

B+树如下所示:

在这里插入图片描述

​ 1) 在B树中每个节点都会存储data和索引;在B+树中则只有叶子节点会存储data和索引,其它的节点只会存储索引。这样的话,每个节点就可以放更多的索引,那么树的高度也就会相应的变矮,查询时做的磁盘IO也会更少

​ 2) 在B+树中叶子节点存储了所有的索引,并且所有的叶子节点之间构成了一个环形的双向链表。这种数据结构,在面对一些范围查询时,只需要确定左右区间就可以根据叶子节点的链表性质取出所有数据。

​ 关于B+树的索引面对上千万的数据时,到底需要走多少次索引?大概是3~5次,在上文中已经能得出,树的高度想要变矮,则需要一个节点存储足够多的索引,B+树的非叶子节点只存储索引字段不存储data,则能尽可能的存储更多的索引。

​ 基于这些主要因素,mysql的索引最终采用了B+树这种数据结构,而我们在对索引进行优化时的各种原则其实也是根据B+树的性质来进行优化的。

​ 最后补充一点,mysql中的索引建立时可以选择索引方法为hash,但是当索引为hash时,就只适用于”=“或者”in“的查询情况了,所以一般来说是不推荐选择hash的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值