InnoDB存储引擎索引——B+树索引

一、InnoDB存储引擎索引概述

* B+ 数索引
* 全文索引
* 哈希索引

InnoDB 存储引擎支持的哈希索引是自适应的,InnoDB 存储引擎会根据表的使用情况自动为表生成哈希索引,不能人为干预是否在一张表中生成哈希索引。
B+ 树索引就是传统意义上的索引,这是目前关系型数据库系统中最为常用和最为有效的索引。B+ 树索引的构造类似于二叉树,根据键值(Key Value)快速找到数据。
B+ 树中的B 不是代表二叉(binary),而是代表平衡(balance),因为B+树是从最早的平衡二叉树演化而来的,但是B+树不是一个二叉树。
还有,B+树索引并不能找到一个给定键值的具体行。B+树索引能找到的只能被查找数据行所在的页。然后数据库通过把页读入到内存,再在内存中进行查找,最后得到要查找的数据。
二、数据结构与算法
B+数索引是最为常见,也是在数据库中使用最为频繁的一种索引。在介绍高索引之前先介绍与之密切相关的一些算法与数据结构。这样有助于理解B+数索引的工作方式。

1. 二分查找法

二分查找法(binary search)也成为折半查找法,用来查找一组有序的记录数组中的某一记录,其基本思想史:将记录有序化(递增或递减)排列,在查找过程中采用跳跃式方式查找,即现以有序数列的终点位置为比较对象,如果要找的元素值小于该中点值,则将待查序列缩小为左半部分,否则为右半部分。通过一次比较,将查找区间缩小一半。
例如:5、10、22、33、37、43、48、51、52这九个数。现要从这10个数中查找43这条记录,其查找过程如下图所示:
这里写图片描述
这是奇数个去中间值((1+9)/2 = 5),如果偶数个((1+8)/2 = 4),取整就好了。
从图中可以看出,用了3次就找到了 43这个数。如果是顺序查找,则需要8次。因此,二分查找法的效率比顺序查找法要好(平均来说)。但如果所要查 5 这条记录,顺序查找只需1 次,而二分查找需要 4次。我们看来,对于上面 10 个数来说,顺序查找平均次数为(1+2+3+4+5+6+7+8+9)/9 = 5。
而二分查找为(3+2+3+4+1+3+2+3+4)/9=2.4.在最坏的情况下,顺序查找次数为9.二分查找为4.

1.     二叉查找树和平衡二叉树

在介绍 B+数前,需要先了解一下二叉查找树。B+树是通过二叉查找树,在由平衡二叉树,B树演化而来。如图,为一个二叉查找树。
这里写图片描述
图中数字代表每个节点的键值,在二叉查找树中,左子树的键值总是小于根的键值,右子树的键值总是大于根的键值。因此可以通过中序遍历得到键值的排序输出,图中的二叉查找树经过中序遍历后输出:
2、3、5、6、7、8
(1. 前根序遍历:先遍历根结点,然后遍历左子树,最后遍历右子树。
2.中根序遍历:先遍历左子树,然后遍历根结点,最后遍历右子树。
3.后根序遍历:先遍历左子树,然后遍历右子树,最后遍历根节点。)
对图中这颗二叉树进行查找,如查键值为5的记录,先找到根,其键值是6,6大于5,因此查找6的左子树,找到3,,而5大于3,查找3的右子树,找到5;一种找了3次。如果按2、3、5、6、7、8这个顺序来找同样需要3次。用同样的方法在查找键值为8的这记录,这次用了3次查找,而顺序查找需要6次。计算平均可得:顺序查找的平均次数为(1+2+3+4+5+6)/6 = 3.3次,二叉查找树的平均次数为(3+3+3+2+2+1)/6 = 2.3次。二叉查找树的平均查找速度比顺序查找来的更快。
二叉树可以任意的构造,同样是2、3、5、6、7、8这五个数字,也可以按下图的方式建立二叉查找树。
这里写图片描述
如图的平均查找次数为(1+2+3+4+5+5)/6 = 3.16次,和顺序查找差不多。显然这课二叉查找树的查询效率就低了。因此若想最大性能地构造一个二叉查找树,需要这棵二叉查找树是平衡的,从而引出了新的定义—平衡二叉树,或称AVL数。
平衡二叉树定义如下:首先符合二叉查找树的定义,其次必须满足任何节点的两个子树的最大高度差为1.显然,上图不满足平衡二叉树的定义。平衡二叉树的性能是比较高的,但不是最高的,只是接近最高性能。最好的性能需要建立一棵最优二叉树,但是最优二叉树的建立和维护需要大量的操作,因此,用户一般只需要建立一棵平衡二叉树即可。
平衡二叉树的查询速度的确很快,但是维护一棵平衡二叉树的代价是非常大的,通常来说,需要1 次或多次左旋和右旋来得到插入或更新后树的平衡性。对于上图来说,当用户需要插入一个新的键值为9的节点时,需要下图的变动。
这里通过一次左旋操作就将插入后的树重新变为平衡的了。但是有的情况可能需要多次
这里写图片描述
插入新值9
这里写图片描述
左旋以保证平衡
左旋就是7的右孩子8变成根节点,7变成8的左孩子

除了插入操作,还有更新和删除操作,不过这和插入没有本质区别,都是通过左旋或者右旋来完后才能的。因此对一棵平衡树的维护是有一定开销的,不过平衡二叉树多用于内存结构对象中,因此维护的开销相对较小。

三、B+树
B+树:B+树是为磁盘或其他直接存取辅助设备设计的一种平衡查找树。在B+树中,所有记录结点都是按键值的大小顺序存放在同一层的叶子节点上,由个叶子节点指针进行连接。先来看一个B+树,其高度为2,每页可以存放4条记录,扇出为5.如下图所示
从图中看出,所有记录都在叶子节点上,并且是顺序存放的,如果用户从最左边的叶子节点开始顺序遍历,可以得到所有键值的顺序飘絮:5、10、15、20、25、30、50、55、60、65、75、80、85、90
这里写图片描述
一棵高度为2的B+树

四、B+树索引
B+树索引的本质就是B+树在数据库中的实现。但是B+索引在数据库中有一个特点是高扇出性,因此在数据库中,B+树的高度一般都在2~4层,这也就是说查找某一键值的行记录时最多只需要2到4次IO,这道不错,因为当前一般的及其磁盘每秒至少可以做100次IO,2~4次的IO意味着查询时间只需0.02~0.04秒。
数据库中的B+树索引可以分为聚集索引(clustered index)和辅助索引(secondary index),但是
不管是聚集索引还是辅助索引,其内部都是B+树索引,即高度平衡的,叶子节点存放着所有的数据。聚集索引与辅助索引不同的是,叶子节点存放的是否是一整行的信息。

* 聚集索引

InnoDB存储引擎表时索引组织表,即表中数据按照主键顺序存放。而聚集索引就是按照每张表的主键构造一棵B+树,同时叶子节点中存放的即为整张表的行记录数据,也将聚集索引的叶子节点称为数据页。聚集索引的这个特性决定了索引组织表中数据也是索引的一部分。同B+树数据结构一样,每个数据页都通过一个双向链表来进行连接。
由于实际的数据页只能按照一棵B+树进行排序,因此每张表只能拥有一个聚集索引。在多数情况下,查询优化器倾向于采用聚集索引。因为聚集索引能够在B+树索引的叶子节点上直接找到数据。此外,由于定义了数据的逻辑顺序,聚集索引能够特别快的访问针对范围值的查询。查询优化器能够快速发现某一段范围的数据页需要扫描。

* 辅助索引(非聚集索引)

对于辅助索引,叶子节点并不包含行记录的全部数据。叶子节点除了包含键值以外,每个叶子节点中的索引行中还包含了一个书签。高书签用来告诉InnoDB 存储引擎哪里可以找到与索引相对应的行数据。由于InnoDB 存储引擎表时索引组织表,因此 InnoDB 存储引擎的辅助索引的书签就是相应行数据的聚集索引。
辅助索引的存在并不影响数据在聚集索引中的组织,因此每张表上可以有多个辅助索引。当通过辅助索引来寻找数据时,InnoDB存储引擎会遍历辅助索引并通过叶级别的指针获得指向主键索引的主键,然后再通过主键索引来找到一个完整的行记录。

猜你喜欢

转载自blog.csdn.net/m0_37899949/article/details/78991700