MySQL数据库索引为什么选择使用B+树?

172 阅读4分钟

这是我参与11月更文挑战的第21天,活动详情查看:2021最后一次更文挑战

1. MySQL数据库索引为什么选择使用B+树?

mysql索引可以使用的数据结构有二叉树、红黑树、B树、B+树等等,可为什么最终选的是B+树呢?我们先来看一下这几种数据结构的特点。

1.1 二叉树

二叉树查找的平均时间复杂度是O(lgn)。如果使用二叉树,在极端情况下(输入的是有序序列),则二叉树会退化成为一条链表,此时平均时间复杂度是O(n)。

理想情况:

image.png

最坏情况:

image.png

1.2 二叉平衡树

二叉平衡树是带有平衡条件的二叉查找树,一般是用平衡因子差值判断是否平衡并通过旋转来实现平衡,左右子树树高不超过1。AVL树查找、插入和删除在平均和最坏情况下都是O(lgn)。但是维护树的代价是非常大,在进行插入或更新时,经常会需要多次左旋或右旋来维持平衡,在数据变动较多时,维护平衡所需的代价可能高于其带来的好处,因此AVL实际使用并不广泛。

1.3 红黑树

红黑树是一种特殊的二叉查找树。红黑树的每个节点上都有存储位表示节点的颜色,可以是红(Red)或黑(Black)。红黑树是为了防止二叉搜索树变为线性数据结构,而出现的数据结构而,AVL树-绝对平衡树的左右子树高度差不能超过1,而红黑树是允许左右子树相差超过1的,因此这种数据结构相对二叉平衡树而言,降低了旋转次数,效率更高,而对于二叉树而言,又减少了树的高度,也就提高了查询的效率,是一种折中的办法。

红黑树的查询平均时间复杂度是O(lgn),但是红黑树的高度不可控,因此在数据量大的情况下,红黑树的高度还是太高了。而树的高度越高,增删改查所需要的IO次数也越多,会严重影响性能。当数据在磁盘中时,磁盘IO会成为最大的性能瓶颈,设计的目标应该是尽量减少IO次数。

1.4 B-树

B-树是一种多叉树,提出B-树的主要目的就是减少磁盘的 I/O 操作,对于B树而言,树的高度将不再是log(n)(其中n是树中的结点个数),而是一个我们可控的高度。

B-树拥有以下几个特点:
1,树高平衡,所有的叶节点都在同一层
2,关键码没有重复
3,B树把值接近的相关记录放在同一个磁盘页中,从而利用了访问的局部性原理。
4,B树保证树种至少有一部分比例的节点是满的

使用B树在大数据的情况下,能减少相对于AVL树和红黑树的查找树高度,减少了IO次数,提高了查询效率。虽然B-树已经很厉害了,但是B+树还做了点优化,进一步降低了高度。

1.5 B+树

更少的IO次数: B+树是应文件系统所需而产生的一种B树的变形树(文件的目录一级一级索引,只有最底层的叶子节点(文件)保存数据)非叶子节点只保存索引,不保存实际的数据,这一点有别于B树。而又因B+树的非叶节点只包含键而无数据,因此每个节点存储的记录个数比B树多(即阶m更大),因此B+树的高度更低,访问时所需要的IO次数更少。

更适于范围查询: 在B树中进行范围查询时,首先找到要查找的下限,然后对B树进行中序遍历,直到找到查找的上限;而B+树的范围查询,只需要去遍历叶子节点就可以实现整棵树的遍历。而且在数据库中基于范围的查询是非常频繁的,而B树不支持这样的操作或者说效率太低。

更稳定的查询效率: B树的查询时间复杂度在1到树高之间(分别对应记录在根节点和叶节点),而B+树的查询复杂度则稳定为树高,因为所有数据都在叶节点,导致每一个数据的查询效率相当。

但是B+树使用索引,因此会使用更多的存储空间来保存索引,但这对与它带来的好处代价要小得多,因此很适合用来做Mysql的索引。