Java相关

Mysql - 索引

2020-04-01  本文已影响0人  万福来

Mysql - 索引原理

索引目的

索引的目的在于提高查询效率,可以类比一本字典,如果要查询某个单词,可以先根据单词首字母查询字典目录,然后找到对应的页码,直接翻到指定页码在进行二分查找,提高查询效率。

磁盘IO与预读

磁盘IO是非常高昂的操作,计算机系统做了一些优化,当一次IO时,不光把当前磁盘地址的数据,而是把相邻的数据也会读取到内存缓冲区,这样可以方便计算机很快访问相邻的数据,这就是磁盘预读。每一次IO读取的数据称之为一页(page),page大小和操作系统有关,一般为4k或8k。

索引数据结构 B+Tree

为了每次查询数据的时候把磁盘IO次数控制在一个很小的数量级,我们需要一个高度可控的多路搜索树。这就是B+Tree。


image.png

浅蓝色为一个磁盘块,每个磁盘块包含几个数据项(深蓝色)和指针(黄色),如磁盘块1包含数据项17和35,包含指针P1、P2、P3表示小于17的磁盘块,P2表示在17和35之间的磁盘块,P3表示大于35的磁盘块,真实的数据只存在于叶子节点。非叶子节点只存储指引搜索方向的数据项,而不存真实的数据。如17、35并不真实存在数据表中。

B+Tree的查找过程

比如要查找数据项29,需要先把磁盘块1加载到内存,发生一次IO,在内存中二分查找29在17和35之间,找到磁盘块1的P2指针;然后在通过P2指针在加载磁盘块3到内存,发生第二次IO,内存中二分查找29在26和30之间,锁定磁盘块3的P2指针;通过指针加载磁盘块8到内存,发生第三次IO,同时二分查找到29,结束查询,总计发生三次IO。

B+Tree性质

联合索引数据结构

image.png

一个SQL只能利用到联合索引中的其中一列进行范围查找,因为B+Tree的每个叶子节点有一个指针指向下一个节点,把某一索引列的所有叶子节点串在了一起,只能根据单列的叶子节点进行范围查询。

Mysql - 索引原则

Mysql - 索引类型

索引主要分为两大类,聚簇索引和非聚簇索引

聚簇索引 (clustered index)

聚簇索引的叶子节点存储行记录,InnoDB必须要有且只有一个聚簇索引:

  1. 如果表定义了主键,则主键索引就是聚簇索引;
  2. 如果没有定义主键,则第一个非空的唯一索引列是聚簇索引;
  3. 如果没有唯一索引,则创建一个隐藏的row-id列作为聚簇索引。主键索引查询非常快,可以直接定位行记录。

非聚簇索引 (secondary index)

InnoDB非聚簇索引的叶子节点存储的是行记录的主键值,而MyISAM叶子节点存储的是行指针。
通常情况下,需要先遍历非聚簇索引获得聚簇索引的主键ID,然后在遍历聚簇索引获取对应行记录。
非聚簇索引需要扫描两遍索引树:又叫回表查询
1、先扫描非聚簇索引根据where条件定位到主键值id=9;
2、再根据主键ID扫描聚簇索引定位到行记录。

回表查询

回表查询就是先定位主键值,在根据主键值定位行记录,需要扫描两遍索引。
解决方案:
只需要在一颗索引树上能够获取SQL所需要的所有列数据,则无需回表查询,速度更快。
常见方法:
将要查询的字段,建立到联合索引里去,这就是索引覆盖
查询sql在进行explain解析时,Extra字段为Using Index时,则触发索引覆盖。
没有触发索引覆盖,发生了回表查询时,Extra字段为Using Index condition.

索引覆盖进行回表查询优化场景

select id, name, sex from table where name = 'tom'; #单列索引(name)联合索引(name,sex),可避免回表
select id, name, sex from table order by name limit 5 ,10 # 单列索引(name)联合索引(name,sex),可避免回表

索引条件下推 (Index Condition Pushdown)

mysql5.6引入了索引下推优化,默认开启,使用 SET optimizer_switch = 'index_condition_pushdown=off'; 可以关闭。
索引下推示例
数据库表中创建了联合索引 (a,b,c)
select * from table where a = 'a' and b like '%b%' and c like '%c%';
没有索引下推技术:
由于b和c使用了like,将导致索引匹配失效,所以只有a字段使用了索引,在索引中通过字段a查询到所有的数据,然后返回服务端,然后在服务端基于模糊匹配条件进行数据过滤。
使用索引下推技术:
可以在索引中首先通过字段a进行查询,然后在根据索引上的b和c判断是否符合模糊匹配条件,如果符合条件则根据该索引来定位对应数据,不符合则直接拒绝,有了索引下推技术,可以在有like条件的情况下减少回表次数,提高查询性能。

上一篇下一篇

猜你喜欢

热点阅读