面试官三连问:给我讲讲什么是索引覆盖?什么是索引下推 ? 什么是最左匹配原则 ?

1.什么是索引覆盖

        索引覆盖是指在一个查询语句中,某个索引已经 "覆盖了" 需要被查询出来的列,此时就不需要进行回表查询了,这就叫做索引覆盖!!(索引覆盖它是非聚簇索引中的一个特殊情况)

【案例】当我们写了这样一个 SQL,实际上它走的是辅助索引,结构如下图:

select id from student where name = 'Bob';

面试官三连问:给我讲讲什么是索引覆盖?什么是索引下推 ? 什么是最左匹配原则 ?_第1张图片

  1. 辅助索引(非聚簇索引)中的查询,一般是需要查询两次,第一次查询出聚簇索引,然后根据聚簇索引回表查询,最终拿到行数据。
  2. 但是此处我的查询需求刚好就是聚簇索引,因此一次查询就可以拿到需要的列,不需要进行回表,这就是索引覆盖~

【加强理解】以下四种情况都属于索引覆盖 >>

// 联合索引 (name,age)
select name from student where.....

select age from student where.....

select name,age from student where.....

select address,name,age from student where address = '深圳';

最后一个 SQL 因为 where 条件后面可以知道 address,所以也不需要回表查询!!

2.什么是索引下推

        索引下推是指在查询非聚簇索时,拿到了叶子结点的聚簇索引,然后对聚簇索引中包含的字段先做判断,直接过滤掉不满足条件的记录,从而减少回表次数,这就是索引下推!!(索引下推是在 MySQL 5.6 之后才引入的,它属于非聚簇索引中功能

以 user 表中的联合索引(name,age)为例:

select * from user where name='张%' and age='10';

// 表中有四条数据
// 1  张三  10
// 2  张四  11
// 3  张五  12
// 4  老六  13

MySQL 5.6 之前没有索引下推,它的执行流程如下:

① 在非聚簇索引中根据 name='张%' 查到聚簇索引中匹配的 id

面试官三连问:给我讲讲什么是索引覆盖?什么是索引下推 ? 什么是最左匹配原则 ?_第2张图片

② 使用匹配的 id 进行回表查询

面试官三连问:给我讲讲什么是索引覆盖?什么是索引下推 ? 什么是最左匹配原则 ?_第3张图片

此时会进行三次回表操作,而联合索引中的 age 字段就没用上。

MySQl 5.6 之后引入索引下推,它会根据 name='张%' 和 age 一起过滤数据:

【好处】:它的第二步操作就可以节省回表的次数

② 使用匹配的 id 进行回表查询

面试官三连问:给我讲讲什么是索引覆盖?什么是索引下推 ? 什么是最左匹配原则 ?_第4张图片

 引入索引下推后,只执行了一次回表查询,这就是索引下推的好处。

3.什么是最左匹配原则

【定义和规则】

  • 最左匹配原则是指索引以最左边的为起点,任何连续的索引都能匹配上,
  • 当遇到范围查询 (>、<、between、like) 就会停止匹配。

什么意思呢 ??

比如联合索引 index(a,b,c),以下 SQL 来理解什么是最左匹配原则:

select * from user where a=1; // 只使用索引 a

select * from user where b=2; // 不使用索引

select * from user where c=3; // 不使用索引

select * from user where a=1 and b=2; // 只使用索引 a,b

select * from user where a=1 and c=3; // 只是用索引 a

select * from user where b=2 and c=3; // 不使用索引

select * from user where a=1 and b=2 and c=3; // 使用索引 a,b,c

select * from user where a=1 and b like '%xxx' and c=3; // 只使用索引 a,b

通过上面的例子,我相信大家已经大概理解了什么是最左匹配原则~

【疑惑一】

        不是说使用了 like,就停止匹配了吗,为什么前面的索引下推使用了 name='张%' 还能再拿 age 进行过滤呢 ?

对于 like 查询,它的常见写法有三种:

  • 模糊匹配后面任意字符:like '张%'
  • 模糊匹配前面任意字符:like '%张'
  • 模糊匹配前后任意字符:like '%张%'

        这三种情况,只有第一种情况是会走索引的,其他的都会导致索引失效,所以前面索引下推例子中的 name='张%' 是不会停止匹配的~

【疑惑二】

        当我们写出这样的条件语句 where a=1 and c=3 and b=2 时,引擎为什么不把它调整为 a,b,c 的顺序呢?

        MySQL 8.0 之后才涉及到这样的调优,但是具体会不会调优,是不一定的,因为索引调优的主动权在索引的优化器里面的,而优化器这个东西,它很玄学,所以不知道它会不会进行调优。

你可能感兴趣的:(MySQl,mysql,数据库)