Mysql(一)索引与算法

INNODB存储引擎概述

存储引擎的索引分类(安装索引的内部实现不同):

  • B+树索引
  • 哈希索引(INNODB是自适应哈希索引)
  • 全文索引

B+树索引就是传统意义上的索引,也就是上面提到过那种类型的索引,这是目前关系型数据库系统中查找最为常用和最为有效的索引。B+树索引的构造类似于二叉树。

哈希索引,INNODB存储引擎是自适应的,INNODB存储引擎会根据表的使用情况自动为表生成哈希索引,不能认为干预是否在一张表中生成哈希索引。

全文索引,会在后面讲述。

B+树

B+树和二叉树、平衡二叉树一样,都是经典的数据结构。B+树是由B树和索引顺序访问方法演化而来,但是在实现使用过程中几乎已经没有使用B树的情况了。

B+树的简单定义:B+树是为磁盘或其他直接存储辅助设备设计的一种平衡查找树。在B+树中,所有的记录节点都是按键值的大小顺序存放在同一层的叶子节点上,由叶子结点指针进行连接。

下面演示一个B+数结构,高度为2,每页可放4条记录,扇出(fan out)为5。从下图1可以看出,所有记录都在页节点中,并且为顺序存放,我们从最左边的叶节点开始遍历,可以得到所有键值的顺序排序:5、10、15、20、25、30、50、55、60、65、75、80、85、90。 

这里写图片描述

1、B+树的插入操作

B+树的插入必须保证插入后叶子节点中的记录依然排序,同时需要考虑插入到B+树的三种情况,每种情况都可能会导致不同的算法。 
这里写图片描述

这里用一个例子来分析B+树的插入。例如,对于上图的这颗B+树,若用户插入28这个键值,发现当前Leaf Page和Index page都没有满,我们直接将记录插入叶节点就可以了。如下图所示: 
这里写图片描述 

下面我们再插入70这个值,这时Leaf Page已经满了,但是Index Page还没有满,符合上面的第二种情况。这时插入Leaf Page的情况为 
50、55、60、65、70.我们根据中间的值60拆分叶节点,可得到下图所示(双项链表指针依然存在,没有画出): 
这里写图片描述 

最后我们再插入95,这个Leaf Page和Index Page都满了,符合上面第三种情况。需要做2次拆分,如下图所示:

这里写图片描述 

可以看到,不管怎么变化,B+树总会保持平衡。但是为了保持平衡,对于新插入的键值可能需要做大量的拆分页操作。B+树主要用于磁盘,拆分意味着磁盘的操作,应该在可能的情况下尽量减少页的拆分。因此,B+树同样提供了类似二叉树的旋转功能。

旋转发生在Leaf Page已经满,但是其左右兄弟节点没有满的情况下。这时B+树并不会急于去做拆分页的操作,而是将记录转移到所在页的兄弟节点上。在通常情况下,左兄弟会被首先检查用来做旋转操作,因此若是最开始插入键值70,其实B+树并不会急于去拆分叶子结点,而是去做旋转操作,如下图所示:
这里写图片描述

2、B+树的删除操作

B+树使用填充因子来控制树的删除变化,50%填充因子可设的最小值。B+树的删除操作同样必须保证删除后叶子结点中的记录依然排序,同插入一样,B+树的删除操作同样需要考虑以下三种情况,如插入不同的是,删除根据填充因子的变化来衡量。 

这里写图片描述 
对上图B+树来进行删除操作。首先删除键值为70的这条记录,该记录符合表讨论的第一种情况,删除后可得到下图: 

这里写图片描述 
接着我们删除键值为25的记录,这也是表中讨论的最后一种情况,但是该值还是Index Page中的值,因此在删除Leaf Page中的25后,还应将25的右兄弟节点的28更新到Page Index中,最后可得到下图: 


这里写图片描述
最后看删除键值为60的情况。删除Leaf Page中键值为60的记录后,Fill factor小于50%,这时需要做合并操作,同样,在删除Index Page中相关记录后需要做Index Page的合并操作,最后得到下图 


这里写图片描述

 

B+树索引

前面讨论的都是B+树的数据结构及其一般操作,B+树索引的本质就是B+树在数据库中的实现。但是B+树索引在数据库中有一个特点就是高扇性,因此在数据库中,B+树的高度一般在2~4层,这也就是说查找某一个键值的行记录时最多只需2到4次IO,这倒不错。因为当前一般的机械磁盘每秒至少可以做100次IO,2~4次的IO意味着查询时间只需0.02秒~0.04秒。

数据库中的索引分为聚集索引和辅助索引,但是不断是聚集索引还是辅助的索引,其内部都是B+树,即高度平衡的,叶子节点存放着所有的数据。聚集索引与辅助索引不同的是,叶子节点存放的是否是一整行的信息。


1、聚集索引

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

2、辅助索引

对于辅助索引,叶子节点并不包含行记录的全部数据。叶子节点除了包含键值以外,每个叶子节点中的索引行中还包含了一个书签。该书签用来告诉InnoDB存储引擎哪里可以找到与索引相对应的行数据。由于InnoDB存储引擎表是索引组织表,因此InnoDB存储引擎的辅助索引的书签就是相应行数据的聚集索引键。
辅助索引并不影响数据在聚集索引中的组织,因此每张表上可以有多个辅助索引。当通过辅助索引来寻找数据时,InnoDB存储引擎会遍历辅助索引并通过叶级别的指针获得指向主键索引(聚集索引)的主键,然后在通过主键索引来找到一个完整的行记录。举例来说,如果在一棵高度为3的辅助索引中查找数据,那么需要对这颗辅助索引树遍历3次找到指定主键,如果聚集索引树的高度同样为3,那么还需要对聚集索引树遍历3次查找,最终找到一个完整的行数据所在页,因此一共需要6次逻辑IO访问以得到最终的一个数据页。
 

倒排索引

全文检索通常使用倒排索引来实现,它在辅助表中存储了单词与单词自身在一个或者多个文档中所在位置之间的映射,这通常利用关联数组实现

常规的索引是文档到关键词的映射:文档——>关键词
倒排索引是关键词到文档的映射:关键词——>文档

全文索引通过关键字找到关键字所在文档,可以提高查询效率

全文搜索

倒排索引需要将word存放到一张表中,这个表成为 辅助表, 为了提高全文搜索的并行性能,共有6张辅助表。

辅助表是持久的表,存放于磁盘上。为了提高全文检索的性能,引入了FTS Index Cache(全文检索索引缓存),是一个红黑树的结构,期根据(word,ilist)进行排序。但是插入数据已经封信了对应的表,对全文索引的更新可能在粉丝操作后还是FTS Index Cache中,辅助表可能还没有更新,InnoDB批量对辅助表更新,而不是每次插入都更新辅助表。

当对全文检索进行查询时,辅助表首先会将在FTS Index Cache中对应的word字段合并到辅助表中,然后在进行查询。

stopword表,表示该列表中的word不需要对其进行索引分词操作

目前仅支持英语,中文,日语,韩语还不支持。

参考:

https://www.cnblogs.com/wxzhe/p/9951333.html

https://blog.csdn.net/finish_dream/article/details/79617576

猜你喜欢

转载自blog.csdn.net/zyh568879280/article/details/88411519