MySQL索引底层数据结构

MySQL相信大家都不陌生,索引的日常使用应该也是比较频繁的,今天就聊一聊索引底层的数据结构;

MySQL索引底层为什么使用B+树而不是二叉树;红黑树;B树?

索引:索引是帮助MySQL高效获取数据的的排好序的数据结构(B+Tree),例如日常看书的目录,可以快速的帮我们定位到我们想看的位置.

1. 二叉树

使用二叉树来做索引的数据结构,每一个节点储存一个索引和当前记录再磁盘所在的位置;
例如我们现在有这么一张表,如下图
在这里插入图片描述
binary_tree_test这张表中有column_1;column_2两个字段;

column_2这个字段来做索引 在这里插入图片描述

如果以column_2这个字段来做索引的话,再使用二叉树的数据结构的情况下是这样的,

select * from binary_tree_test where column_2 = 66;

这条sql查询,再使用索引的情况下,再底层的结构中只需要37->73->66作比较,最后查询到我们想要的column_2 = 66的数据;比较三次,从这一点看还是狠快的;好像没有什么问题;接下来看下一种情况

column_1这个字段来做索引

在这里插入图片描述
如果使用column_1这个字段来做索引,那么它底层的结构就应该是这样的.

select * from binary_tree_test where column_1 = 6;

上面这条sql查询,在使用索引的情况下,在底层的数据结构中,需要1->2->3->4->5->6做6次比较,基本上跟没有使用索引进行全表扫描是没什么区别的;效率会非常低的;没有太大的提升
总结:二叉树这种数据结构再对单边增长的数据/列,对于我们查找的效率并没有什么显著的提升,搜索的数值越大,越接近全表扫描,这也是MySQL为什么不使用二叉树来做索引底层的数据结构的原因

2. 红黑树(二叉平衡树)

红黑树又叫二叉平衡树,这种数据结构跟二叉树类似,但是比二叉树多一个自动平衡的功能,根节点左右两边,一边比另一边的树的高度要高的多的时候,会通过变色或者旋转的方式自动平衡;
binary_tree_test表使用column_1这个字段来做索引
在这里插入图片描述
如果索引底层是红黑树的情况下,binary_tree_test表使用column_1这个字段来做索引就不会再出现一边倒的二叉树了,因为红黑树可以帮我们自动平衡;

select * from binary_tree_test where column_1 = 6;

我们再获取column_1 = 6的数据时,只需要跟2->4->6依次比较就可以了,这样下来比较了3次,是要比使用二叉树的效率提升很多的,虽然看起来使用红黑树是要比使用二叉树的效率高很多,但是红黑树依然不是MySQL索引选中的数据结构,具体原因是因为上面例子是一个数据量非常比较小的表,但是再我们生产环境下是没有数据量这么小的表的,基本上都是几十万几百万甚至上千万的数据量,随着数据量越来越多的情况下,我们红黑树的高度也会越来越高,假设树的高度是50,我们查询的元素刚好再底层的叶子节点,我们就需要从根节点一直比较,直到第50次比较到叶子节点获取到我们要的数据为止.同学们设想一下,50次比较,50次的磁盘IO效率同样不会很高
总结:再数据量越来越大的情况下,红黑树的高度不可控,查询的数据越接近根节点效率越高,越接近叶子节点效率越低.使用红黑树来做MySQL索引的底层数据结构同样不理想

3:B树

  • B树所有索引元素不重复
  • 叶节点具有相同的深度,叶节点的指针为空
  • 节点中的数据索引从左到右依次递增排列
    在这里插入图片描述
    如图,B树每个节点中不仅存放着索引,并且还储存着当前列的数据data;mysql对B树的每一块节点的大小规定的是16K,当一块节点分配出去以后,mysql会直接再磁盘上画出16K的空间用来储存当前块的节点
    在这里插入图片描述
    总结:假设我们使用B树来做我们的Mysql的底层数据结构,在使用bigint来做我们的索引的话,bigint再Mysql中占8个字节,每一列的数据假设占用1KB,那么我们三层才可以储存16×16×16=4096条数据,数据量过大的时候我们的B树的高度同样不可控,数据量越大效率会越低,所以Mysql同样不会使用B树来做底层的数据结构

4:B+树

  • B+树为了储存更多的索引,非叶子节点不储存当前列的数据再磁盘中的地址data,只储存索引;非叶子节点储存的索引都相当于冗余索引,再叶子节点还会有该索引的值
  • 叶子节点储存着所有的索引字段
  • 叶子节点用双向指针连接,提高区间访问的性能
  • B+树同样的也是从左到右依次递增排列的
    在这里插入图片描述
    B+树不仅使用了双向指针来连接叶子节点,还是用了指针来连接上层节点和下层节点,上层节点储存着下次节点的地址;方便我们可以更快的进行查询;
    常驻内存机制:Mysql会把B+树的非叶子节点中的数据提前加到内存中,减少不必要的IO次数,方便我们更快的查询.

使用B+树是否还会出现树的高度不可控的情况?

  1. 不会;从前面几个数据结构的判断中,我们大概都清楚了,决定我们的效率的往往是树的高度,树的高度越低,经历的磁盘IO的次数就越少,效率也会越高,而我们B+树的高度是由我们的非叶子节点可以存放多少的数据而决定的,所以B+树使用冗余索引,把data放在叶子节点上去,就是为了非叶子节点的可以储存更多的元素
  2. 假设我们使用bigint来做我们的索引;一个bigint的索引大概再mysql占用8个字节,存放着下层节点的指针再C语言中占6个字节;16KB÷(8B+6B)=1170;顶层节点可以存放1170个节点;第二层每个节点块也可以储存1170个节点;叶子节点正常情况下一列约等于1KB的元素,每个叶子节点就可以储存16个索引;B+树三层的情况下可以储存1170×1170×16=21902400个元素;2190万条数据的表常驻内存机制加上B+树作为我们底层数据结构时,mysql还会把非叶子节点的节点块给提前放到内存中(常驻内存机制);节省掉不必要的磁盘IO;我们的查询再底层只需要经历一次磁盘IO就可以完成,效率比其他的数据节点快的不是一点点;而且数据量越大,使用B+树的效率提高越明显
  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

.番茄炒蛋

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

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

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

打赏作者

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

抵扣说明:

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

余额充值