前言
上一篇博客我们讲到了B-树索引,但是其实大家都知道Mysql(MYISAM和InnoDb)最终使用的是B+树索引,那么这么做的原因是什么?这也就是接下来的内容。
B-树索引存在的问题
问题1
:索引+数据内容分散在不同结点上,距离根结点近搜索就快,距离根结点远搜索就慢,也就是花费的磁盘IO的次数不平均,每一行数据搜索花费的时间也不平均;问题2
:每一个非叶子结点上不仅仅要存索引(key),还要存储索引值所在的那一行的数据,一个结点(固定大小)所能存放的索引key值的个数比只存储key值的结点的个数少得多!!问题3
:不方便做范围搜索(where-between),整表搜索也不方便。
由上面的三个原因,导致我们采用B+树构建索引树。
只有对比才知道B+树的好处
B-树
的每一个节点,存了关键字和对应的数据地址,B+树
的每一个非叶子节点只存关键字,不存数据地址。因此B+树的每一个非叶子节点存储的key是远远多于B-树
的,B+树
的叶子节点存放所有的key和对应的data,因此,从树的高度上来说,B+树
的高度要小于B-树
,使用的磁盘I/O次数少,因此查询会更快一些。B-树
由于每个节点都存储关key和data,因此离根节点进的数据,查询的就快,离根节点远的数据,查询的就慢;B+树
所有的数据都存在叶子节点上,因此在B+树
上搜索关键字,找到对应数据的时间是比较平均的,没有快慢之分,因为搜索每一个key对应的data都需要跑到叶子结点去。- 在
B-树
上如果做区间查找或者整表搜索,遍历的节点是非常多的;而B+树
所有叶子节点被连接成了有序链表结构,因此做整表遍历和区间查找是非常容易的, 直接遍历叶子结点的有序链表即可。
索引的底层原理
博主靠个人理解陈述,如有错误请指正:
当我们执行一条查询语句搜索时,如果添加了过滤条件,mysql server会先检查该字段是否有索引,如果没有就会做整表搜索,效率较低,如果有,底层kernal会把磁盘上的索引文件中(*.ibd
)的索引数据加载到内存上,用B+树构建索引(B+树是一个平衡树,搜索效率高,B+树会一个节点一个节点构建,一个节点就对应一次磁盘IO,非叶子结点存放的都是key,所有的key和data都是存放在叶子结点的),所以以B+树构建的索引树会以最少的磁盘IO次数和二分搜索的效率来搜索数据。
在回答面试问题时,也可以拓展讲一讲B和B+的对比。