MySQL用B+树(而不是B树)作索引的缘由

众所周知,MySQL的索引使用了B+树的数据结构。那么为何不用B树呢?
先看一下B树和B+树的区别。mysql

B树

维基百科对B树的定义为“在计算机科学中,B树(B-tree)是一种树状数据结构,它可以存储数据、对其进行排序并容许以O(log n)的时间复杂度运行进行查找、顺序读取、插入和删除的数据结构。B树,归纳来讲是一个节点能够拥有多于2个子节点的二叉查找树。与自平衡二叉查找树不一样,B-树为系统最优化大块数据的读和写操做。B-tree算法减小定位记录时所经历的中间过程,从而加快存取速度。广泛运用在数据库和文件系统。”算法

B 树能够看做是对2-3查找树的一种扩展,即他容许每一个节点有M-1个子节点。sql

定义

  • 根节点至少有两个子节点
  • 每一个节点有M-1个key,而且以升序排列
  • 位于M-1和M key的子节点的值位于M-1 和M key对应的Value之间
  • 其它节点至少有M/2个子节点

下图是一个M=4 阶的B树:
数据库

能够看到B树是2-3树的一种扩展,他容许一个节点有多于2个的元素。缓存

B树的插入及平衡化操做和2-3树很类似,这里就不介绍了。数据结构

B+树

B+树是对B树的一种变形树,它与B树的差别在于:性能

  • 有k个子结点的结点必然有k个关键码。
  • 非叶结点仅具备索引做用,跟记录有关的信息均存放在叶结点中。
  • 树的全部叶结点构成一个有序链表,能够按照关键码排序的次序遍历所有记录。

以下图是一个B+树:
优化

B+树和B树的区别

B+树的非叶子结点只包含导航信息,不包含实际的值,全部的叶子结点和相连的节点使用链表相连,便于区间查找和遍历。指针

B+ 树的优势在于:blog

  • IO次数更少:因为B+树在内部节点上不包含数据信息,所以在内存页中可以存放更多的key。 数据存放的更加紧密,具备更好的空间局部性。所以访问叶子节点上关联的数据也具备更好的缓存命中率。
  • 遍历更加方便:B+树的叶子结点都是相链的,所以对整棵树的遍历只须要一次线性遍历叶子结点便可。并且因为数据顺序排列而且相连,因此便于区间查找和搜索。而B树则须要进行每一层的递归遍历。相邻的元素可能在内存中不相邻,因此缓存命中性没有B+树好。

可是B树也有优势,其优势在于,因为B树的每个节点都包含key和value,所以常常访问的元素可能离根节点更近,所以访问也更迅速。
下面是B 树和B+树的区别图:

为何MySQL选择B+树作索引

  • B+树的磁盘读写代价更低:B+树的内部节点并无指向关键字具体信息的指针,所以其内部节点相对B树更小,若是把全部同一内部节点的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多,一次性读入内存的须要查找的关键字也就越多,相对IO读写次数就下降了。

  • B+树的查询效率更加稳定:因为非终结点并非最终指向文件内容的结点,而只是叶子结点中关键字的索引。因此任何关键字的查找必须走一条从根结点到叶子结点的路。全部关键字查询的路径长度相同,致使每个数据的查询效率至关。

  • B+树更便于遍历:因为B+树的数据都存储在叶子结点中,分支结点均为索引,方便扫库,只须要扫一遍叶子结点便可,可是B树由于其分支结点一样存储着数据,咱们要找到具体的数据,须要进行一次中序遍历按序来扫,因此B+树更加适合在区间查询的状况,因此一般B+树用于数据库索引。

  • B+树更适合基于范围的查询:B树在提升了IO性能的同时并无解决元素遍历的我效率低下的问题,正是为了解决这个问题,B+树应用而生。B+树只须要去遍历叶子节点就能够实现整棵树的遍历。并且在数据库中基于范围的查询是很是频繁的,而B树不支持这样的操做或者说效率过低。

相关文章
相关标签/搜索