首先列举下在面试过程当中对于B+树索引常见的两个问题,但愿经过本文简要解决这些问题:mysql
众所周知,一颗传统的M阶B+树须要知足如下几个要求:面试
B+树是为了磁盘及其余存储辅助设备而设计的一种平衡查找树(不是二叉树),在B+树中,全部记录的节点按大小顺序存放在同一层的叶节点中,各叶子节点用指针进行链接,而B+树索引本质上就是B+树在数据库中的实现,与纯粹的B+树数据结构仍是有点区别。sql
B+树与B+树索引的区别以下:数据库
B+树 | B+树索引 | |
---|---|---|
存储位置 | 内存 | 磁盘 |
扇出率 | 低 | 高 |
并发控制 | 能够不考虑 | 需考虑 |
分裂方向 | 不须要考虑 | 向左、向右 |
一般来讲,B+树索引用于基于磁盘的数据库系统,即数据最后持久化存放在磁盘上,每一个页的叶子节点通常包含较多的记录,所以具备较高的扇出。这意味着在数据库中B+树索引高度通常较小,在2~3层,其高度也决定了磁盘I/O搜索的次数数据结构
还有一点须要注意的是,实际上根据B+树索引并不能找到一个给定值的具体行,B+树索引能找到的只是查找数据行所在的页。而后数据库经过把数据页读入内存,再在内存中进行查找,最后获得查找的数据。并发
B+树是上世纪70年代针对硬盘和单核处理器设计的,为了减小机械硬盘的寻道次数,它采用了多叉树结构,下降了索引结构的深度,IO读写次数减小。性能
熟悉数据结构的同窗都知道,B树也是多叉树结构,一种自平衡的树,并且B+树是从B树演化而来的,那么为何不使用B+树的前身B树呢?一些资料也代表B树也适用于读写相对大的数据块的存储系统,例如磁盘。下面来看下用B树作索引的结构:.net
上图小红方块表示文件内容在硬盘中的存储位置。B树相比B+树的一个主要区别就在于B树的分支节点上存储着数据,而B+树的分支节点只是叶子节点的索引而已。设计
从上面比较B+树和B树的结构,能够得出为何使用B+树作索引的一些缘由(其实网上写B+树索引谈到的大都是如下这些缘由):指针
1. B+树的磁盘读取代价低
B+-tree的内部节点并无指向关键字具体信息的指针,换句话说,即分支节点没有存储数据,所以其内部节点相对B 树更小。若是把全部同一内部节点的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多。一次性读内存中的须要查找的关键字也就越多。相对来讲IO读写次数也就下降了。
2. B+树的查询效率更加稳定
在B+树中,因为分支节点并非最终指向文件内容的节点,分支节点只是叶子节点的索引,因此对于任意关键字的查找都必须从根节点走到分支节点,全部关键字查询路径长度相同,每一个数据查询效率至关。而对于B树而言,其分支节点上也保存有数据,对于每个数据的查询所走的路径长度是不同的,效率也不同。
3. B+树便于执行扫库操做
因为B+树的数据都存储在叶子节点上,分支节点均为索引,方便扫库,只需扫一遍叶子便可。可是B树在分支节点上都保存着数据,要找到具体的顺序数据,须要执行一次中序遍从来查找。因此B+树更加适合范围查询的状况,在解决磁盘IO性能的同时解决了B树元素遍历效率低下的问题
再次总结下B+树索引,它采用了多叉树的结构,下降了索引结构的深度,避免了传统二叉树结构中绝大部分的随机访问操做,有效减小了磁盘磁头的寻道次数。B+树索引查询效率稳定,也有利于进行范围查询。