为什么MySQL用B+树做索引而不使用其他的数据结构呢?

为什么不用数组?

数组这个数据结构,对于我们来说算是最熟悉的老朋友了,自从JAVASE时我们就接触它,对于一个有序数组,我们进行查找和修改操作效率是非常高的,并且在不考虑空洞的情况下删除操作也非常快,因为只需要将此处元素置为null,但如果我们要在数组中间的任意一个位置插入一个数据,那么必然会引起该位置后面所有数据位置的变化,也就是涉及到了数组的复制,而插入的位置越往前,所需要复制的数据就越多,该过程不仅需要消耗大量的内存,而且还会浪费大量的时间,因此从插入数据的场景来看,数组并不适合作为MySQL索引的数据结构!

为什么不用哈希表?

在MySQL中我们经常需要查找某个范围内的数据,例如between…and,>=,<=等,由于哈希表所有的key都会先经过哈希函数计算,再将数据存放到对应的位置本来可能有序的key通过哈希函数计算之后导致其存放不有序了,因此如果我们在哈希表中进行范围查找,只能通过遍历的方式,当数据量过大的情况下,对于哈希表的整个遍历是非常耗时的。

因此从范围查询的场景来看,哈希表也不太适合作为MySQL索引的数据结构,它适合等值查询,例如我们常用的redis数据库都是key-value的形式且无序。

为什么不用二叉树?

我们最常用的二叉树有二叉搜索树,平衡树,红黑树

无论是二叉搜索树,平衡树还是红黑树,他们的特点都是每个节点最多只有两个子节点,如果存储大量数据的话,那么树的高度就会非常高,而MySQL存储的数据最终是要到磁盘的,MySQL应用程序读取数据时,需要将数据先从磁盘加载到内存后才能继续操作,所以这中间会发生磁盘IO,而如果树的高度太高,每遍历一层结点时,就需要从磁盘读取一次数据,也就是发生一次 IO,假设数据在树高为 20 的地方,那查找一次数据就得发生 20 次 IO,耗时太长了。

因此二叉树在 MySQL 这种需要存储大量数据的场景下,是不适合当做索引的数据结构的,因为树太高,操作数据时会发生多次磁盘 IO,性能太差。

为什么使用B+Tree?

既然二叉树因为每个结点最多只有两个子结点,最终在存储大量数据时导致树太高,那么让树的每个结点尽可能多的拥有多个子结点也就是多叉树,这样在大量储存数据时,树就低很多了,能够实现该功能的数据结构正是多叉树中典型B-Tree 和 B+Tree

B-Tree 的特点是无论叶子结点还是非叶子结点,它都存有索引值和数据B+Tree 的特点是只有叶子结点才会存放索引值和数据,非叶子结点只会存放索引值本身。由于一个结点的空间是有限的,B-Tree 要存放索引+数据,而 B+Tree 只需要存放索引,因此对于非叶子结点,一个结点中,B+Tree 存放的索引值数量会远远大于 B-Tree,这样就导致了每个结点中,B+Tree 能向下分出更多的叉,子结点数更多。

那么在存储同样大小数据的场景下,用 B+Tree 存储,最终树的高度会远远小于用 B-Tree 存储的高度,所以使用 B+Tree 作为 MySQL 索引的数据结构,在读取数据时,发生的磁盘 IO 次数会更少,性能更优,因此最终 MySQL 索引的数据结构使用的是 B+Tree。

  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

从未止步..

谢谢你的打赏,我会继续努力!

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

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

打赏作者

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

抵扣说明:

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

余额充值