[MySQL] InnoDB 索引

227 阅读5分钟

[MySQL] InnoDB 索引

 InnoDB中索引分为以下几类:

  • B+树索引

 B+树索引是MySQL InnoDB引擎的最基础最常用索引类型。

  • 哈希索引

 InnoDB中的哈希索引是自适应哈希索引,引擎会自动根据访问的频率和模式自动的为某些热点页建立哈希索引。

  • 倒排索引

 倒排索引主要是针对全文检索来提供的解决方案。

一、数据结构和算法

  • 二分查找算法

 二分查找主要用在主要是Page Directory(页目录)中查找具体的某一记录,也就是说先查找一条记录先B+树查询,然后二分查找。

  • B+树数据结构

 这里一般B+树的层级(高度)为2~4层,也就是查询一条记录最多查询4次。

二、B+树索引

注意:B+树索引索引能够找到的只是被查找数据所在的页,然后将页数据load到内存中,在内存中查找到对应的行记录,并非直接查找到对应的行数据。

  • 聚集索引

 聚集索引是指叶子节点存放有数据的B+树索引,因此聚集索引的叶子节点也被称为数据页。叶子节点之间使用双向链表来连接,每个数据页之间的记录也是通过双线链表来连接的。但是注意这里是逻辑上的存储结构,而非物理上的存储结构。

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

 辅助索引同样是B+树索引,但是叶子节点并不存储数据,叶子节点存储的包含有对应辅助索引的key以及聚集索引的key。

 如果查询辅助索引得到结果,那么还得再从聚集索引中查询得到具体的数据,这一过程被称为“回表”。

  • 联合索引

 联合索引就是使用多个列来创建索引,也就是说每个非叶子节点现在存储的不是一个key值,而是多个key值,注意联合索引有一个最左匹配原则,即使sql语句中写的并不严格的遵守最左匹配原则,sql优化器也会分析后重写成为最左匹配原则的sql语句后执行。

  • 覆盖索引

 覆盖索引,即从辅助索引中可以查到的记录,就不需要查询聚集索引中的记录,辅助索引并不包含整个行数据,因此查询起来会更快。

注意:这里是针对联合索引来讲的。

三、B+树索引优化

  • MRR(Multi-Range Read)

 MRR即将随机读转换成为顺序读,在查询辅助索引得到聚集索引的key之后,对聚集索引的key进行排序转换为顺序读之后再去从聚集索引中取出数据。

  • ICP(Index Condition Pushdown)

 ICP即索引条件下放,所谓索引条件下放即将where过滤条件下放至引擎层去做过滤。

四、哈希索引

  • 哈希算法

 哈希算法是为了解决直接寻址的关键字域过大而需要太大的直接寻址范围演变而来的。哈希算法需要关注以下两个点:

  1. 哈希函数如何设计

 哈希函数设计的要尽可能的使哈希结果均匀,尽可能的减少哈希碰撞,一般有三种方式来实现:1.乘法散列 2.除法散列 3.全域散列 InnoDB中采用除法散列,即 h(k) = k mod m。

  1. 哈希冲突如何处理

 哈希冲突的处理方式算法角度来讲有三种:1.再次哈希 2.线性探测 3. 开链法 InnoDB中采用开链法。

  • InnoDB中的哈希算法

 InnoDB中哈希算法使用缓存池中页的数量的2倍向上取最近质数作为被取余数来分配哈希槽。

 将表空间的space_id和页的相对偏移offset结合来取余。算法如下:

slot = (space_id<<20 + space_id + offset)%((page_num * 2)取大于的最近质数)

  • 自适应哈希索引

 InnoDB存储引擎会监控表上的索引页的查询,如果使用哈希索引能够提升查询速度,就会创建哈希索引。哈希索引并不是给表内所有的数据创建哈希索引,而是根据访问频率和模式自动的为热点的数据依据缓冲池中的B+树页来构造哈希索引。

 访问模式一样是指查询条件一样。并且必须满足以下条件:

1.以该模式访问了100次。 2.页通过该模式访问了N次,其中N=页记录数*1/16

 默认的自适应哈希是开启状态。

五、全文索引

  • 倒排索引

 假设需要进行全文搜索,那么就得知道对应的词在哪些文档中出现过,因此必不可少的就是分词了,倒排索引在es中也有用,es用的是lucence做底层的倒排索引的实现。

 简单来说就是将文本内容进行分词,分词后将文档存储分为主表和辅助表,主要存储文档id和文档的对应关系,辅助表用来存储单词在哪些文档出现过,依据辅助表存储的内容不同分为下面两种表现形式:

  1. inverted file index , 表现形式为{单词,单词所在文档id}

 例子: code {1,3} 那么 code就在1号和3号文档中出现过

  1. full inverted index , 表现形式为{单词,(单词所在文档id,单词所在文档位置)}

 例子: code {(1:3,10),(3:4,20)} 那么 code就在1号文档偏移的3和10的位置都出现了,3号文档中偏移为4和20的位置也都出现过

  • InnoDB中的全文检索  InnoDB中采用的是full inverted index,在全文检索的辅助表中存在ilist列(documentId, position)和word两个列。

 辅助表是一个持久化的表,为了提高并行搜索性能,InnoDB将辅助表按照word的Latin编码进行了分区,分为了6个分区表。

 FTS Index Cache是InnoDB中为了加速全文索引进行的一个缓存,依据(word, iilist)进行排序,采用红黑树来实现。