MySQL——5、B+树索引

mysql数据库中的索引是基于hash表或B+树

1.1 *H**ash索引*

哈希索引就是采用一定的哈希算法,把键值换算成新的哈希值,检索时不需要类似B+树那样从根节点到叶子节点逐级查找,只需一次哈希算法,即可立刻定位到相应的位置,速度非常快。

1.1.1 *B+树索引和哈希索引区别*

B+树索引和哈希索引的明显区别是:

1、 如果是等值查询,那么哈希索引明显有绝对优势,

因为只需要经过一次算法即可找到相应的键值;当然了,这个前提是,键值都是唯一的。如果键值不是唯一的,就需要先找到该键所在位置,然后,再根据链表往后扫描,直到找到相应的数据;

2、 如果是范围查询检索,这时候哈希索引就毫无用武之地了

因为原先是有序的键值,经过哈希算法后,有可能变成不连续的了,就没办法再利用索引完成范围查询检索;

3、 同理,哈希索引也没办法利用索引完成排序,以及like ‘xxx%’ 这样的部分模糊查询(这种部分模糊查询,其实本质上也是范围查询);

Hash支持“<=>”,b+树支持“<=>like in or between ”

4、 哈希索引也不支持多列联合索引的最左匹配规则;

5、 B+树索引的关键字检索效率比较平均,不像B树那样波动幅度大,在有大量重复键值情况下,哈希索引的效率也是极低的,因为存在所谓的哈希碰撞问题。

1.1.2 *M**ysql中应用*

在MySQL中,只有HEAP/MEMORY引擎表才能显式支持哈希索引(NDB也支持,但这个不常用),InnoDB引擎的自适应哈希索引(adaptive hash index)不在此列,因为这不是创建索引时可指定的。

还需要注意到:HEAP/MEMORY引擎表在mysql实例重启后,数据会丢失。

通常,B+树索引结构适用于绝大多数场景

1.1 *B+树索引*

1.1.1 *B-树/B树*

1.1.1.1 *索引为什么使用树结构*

要弄明白B+树,先要弄明白B-树,B-树就是B树,中间的横线不是减号

1、数据库索引为什么要使用树结构进行存储?

树的查询效率高,并且可以保持有序

2、为什么没有使用二叉查找树树来实现?

二叉查找树查询的时间复杂度是O(logN),从算法逻辑上来讲,二叉查找树的查找速度和比较次数都是最小的,但需要考虑一个现实问题:磁盘IO

数据库索引是存储在磁盘上的,当数据量比较大的时候,索引的大小可能有几个G,甚至更多

当我们利用索引查询的时候,不能将整个索引全部加载到内存中,能做的只有逐一加载每一个磁盘页,这里的磁盘页就对应着索引树的节点

img img

如果利用二叉查找树作为索引结构,假设树的高度是4,查找的值是10,则流程如下:

img

imgimg

imgimg

可以看到:

磁盘IO的次数由索引树的高度决定,即最坏查找情况下,磁盘IO的次数等于索引树的高度

为了减少磁盘IO的次数,就需要将将原本“瘦高”的树结构变得“矮胖”,这就是B树的特征之一

1.1.1.2 *B树的特征*

B树是一种多路平衡查找树,它的每一个节点最多包含K个孩子,K被称为B树的阶,K的大小取决于磁盘页的大小

一个m阶的B树具有如下几个特征:

1、 根结点至少有两个子女。

2、 每个中间节点都包含k-1个元素和k个孩子,其中 m/2 <= k <= m

3、 每一个叶子节点都包含k-1个元素,其中 m/2 <= k <= m

4、 所有的叶子结点都位于同一层。

5、 每个节点中的元素从小到大排列,节点当中k-1个元素正好是k个孩子包含的元素的值域分划。

示例:以一个3阶B树为例:

img

重点看(2,6)节点:

该节点中有两个元素2,6,有三个孩子1,(3,5),8

其中1小于元素2,(3,5)在元素2,6之间,8大于(3,5)(规则5)

均符合B树的几条特征

1.1.1.3 *B树的查询过程*

B树的查询过程如下:如果B树中查询数值5

img img

img img

img img

整个流程中,我们可以看出:

B树中的查询次数并不比二叉查找树少,尤其当单一节点中的元素数量很多时,可以相比磁盘IO的速度,内存中的比较耗时,可以忽略不计,

即次数查找是在磁盘IO中查找的,元素比较是在内存中进行的

磁盘读取时,不是按需读取的,而是读取当前数据,并向后读取一段数据,将这段数据加载到内存中,默认这段数据为一页,或页的整数倍,

B树添加节点的时候,默认申请一个磁盘页的空间,用来存储一个节点的数据,这样每个节点只需要一次IO,就可以完全载入

一个节点的数据需要通过一次磁盘IO进行读取,读取到内存中,节点中的数据比较,则是在内存中进行

只要树的高度足够低,IO的次数足够少,就可以提升查找性能。节点内部元素多一些,没有关系,仅仅是多了几次内存交互而已,只要不超过磁盘页的大小即可,这也是B树的优势之一

1.1.1.4 *B树的插入过程*

B树的插入删除过程比较复杂,可以看一个典型的例子:

示例:加入插入的值4:

自顶向下查找4的节点位置,发现4应当插入到节点元素3,5之间。

imgimg

动画演示:https://www.cnblogs.com/vincently/p/4526560.html

可以看到:

为了插入一个元素,整个B树中,很多节点都发生了连锁改变,但这也是B树的一大特点,始终能够维持多路平衡,即自平衡

1.1.1.5 *B树的删除过程*

示例:删除元素11

自顶向下查找元素11的节点位置。

img

删除11后,节点12只有一个孩子,不符合B树规范。因此找出12,13,15三个节点的中位数13,取代节点12,而节点12自身下移成为第一个孩子。(这个过程称为左旋)

img

1.1.1.6 *B树的实际应用*

B树主要应用与文件系统,以及部分数据索引,如非关系型数据库MongoDB,大部分关系型数据库,如MySql,使用B+树作为索引

1.1.2 *B+树实现细节是什么样?*

1.1.2.1 *B+树的特征*

一个m阶的B+树具有如下几个特征:

1、 有k个子树的中间节点包含有k个元素(B树中是k-1个元素),每个元素不保存数据,只用来索引,所有数据都保存在叶子节点。

2、 所有的叶子结点中包含了全部元素的信息,及指向这些元素的指针,且叶子结点本身依关键字的大小自小而大顺序链接。

3、 所有的中间节点元素都同时存在于子节点,在子节点元素中是最大(或最小)元素。

示例:

img

可以看到:

每一个父节点的元素都出现在了子节点,是子节点中的最大(或最小)元素

根节点的最大元素,就等同于整个B+树的最大元素

由于父节点的元素都包含在了子节点中,因此所有叶子节点包含了全量元素信息

每一个叶子节点都带有指向下一个节点的指针,形成了一个有序链表

B+树有卫星数据,即索引元素所指向的数据记录,比如数据库中的某一行,

在B-树中,无论中间节点还是叶子节点,都带有卫星数据

B+树中,只有叶子节点带有卫星数据,其他中间节点仅仅是索引,没有任何数据关联

imgimg

在数据库的聚集索引中,叶子节点直接包含卫星数据,在非聚集索引中,叶子节点带有指向卫星数据的指针

1.1.2.2 *B+树的查询*

B+树的好处主要体现在查询性能上

2 *单行查询*

在单元素查询的时候,B+树会自顶向下逐层查找节点,最终找到匹配的叶子节点

示例:查找元素3

imgimg

img

注意:B+树的查询看起来与B树差不多,但实际上有两点不同:

1、 B+树的中间节点没有卫星数据,所以,同样大小的磁盘页,B+树的磁盘页可以容纳更多的节点数据

即数据量相同的情况下,B+树的结构比B-树更加“矮胖”,因此,查询时,IO次数更少

2、 B+树的查询必须通过查找叶子节点,而B树只需要找到元素即可,无论匹配的元素是处于中间节点,还是叶子节点

因此,B树的查找性能不稳定,最好的情况是查找到根节点,最坏的情况是查找到叶子节点

而B+树的查找性能是稳定的,每一次都固定查找到叶子节点

3 *范围查询*

B+树的范围查询,要远远好于B树的范围查询

示例:查询3到11的元素

B树的查找过程:

需要依靠繁琐的中序遍历

imgimg

imgimg

img

B+树的查找过程:

只需要在叶子节点的链表上做遍历即可

imgimg

img

B+树相对于B树而言,优势有:

1、 IO次数更少;

2、 查询性能更稳定;

3、 范围查询简便;

3.0.1 *B-树与B+树的区别?*

B+树相对于B树的优势:

1.单一节点存储更多的元素,使得查询的IO次数更少。

2.所有查询都要查找到叶子节点,查询性能稳定。

3.所有叶子节点形成有序链表,便于范围查询。

B+树是以空间换时间啊 ,因为子节点都包含父节点的元素。树的层数和一个节点被重复存储成线性关系

的确是以空间换时间。父节点元素在子节点重复出现,增加了少量空间,换来的是范围查询的便利。

那还要B-树有何用?

B-树的好处是,虽然查询性能不稳定,但平均的查询速度快一些(不用每次都查找到叶子节点为止)

为什么要强调B+树查询性能稳定呢?有特殊的应用场合么?

B+树的查询每次都查到叶子节点,所以IO次数稳定。试想一个数据库的查询,有时候执行10毫秒,有时候执行100毫秒,肯定是不太合适的。还不如每次都执行30毫秒

3.0.2 *联合索引在B+树中如何存储?*

简单的说,联合索引就是把多个索引值拼接成一个字符串A,字符串A像普通索引一样保存在索引树中。

posted on 2021-10-13 09:57  夜萤火虫和你  阅读(283)  评论(0编辑  收藏  举报

导航