回表和覆盖索引

回表

在理解回表之前,需要了解聚簇索引和非聚簇索引

InnoDB,由聚簇索引和辅助键索引。

聚簇索引就是将主键值和数据放在一起存储。

辅助键索引就是将索引值和主键值放在一起存储。

表数据

表中有4列,其中ID是主键,设置age为普通索引。

表数据

索引

索引的底层

执行SQL语句:

1
SELECT ID,age FROM USER WHERE age = 19

此时我们只需要通过普通索引就可以找到查询结果。因为在普通索引中有存储age和ID值

我们可以看这句SQL语句的执行计划

执行计划

使用到了索引age_index

查询路径

执行SQL语句

1
SELECT ID,age,`enable` FROM USER WHERE age = 19

此时就需要回表了。

因为我们需要查询了不仅仅是ID和age,还需要enable,无法在普通索引中查询到全部字段。因此需要在主键索引创建的索引树中查找。

查看这条SQL语句的执行计划

image-20210904194433634

这条SQL我们依旧使用到了age_index索引,但是注意,在Extra中没有了Useing index

查询路径

查询路径

总结:

回表就是先通过普通索引找到主键值,然后再根据主键来查询其他的字段。

覆盖索引

在查询时,出现回表会降低性能。那么,如何避免回表查询?

如果辅助索引上已经存在我们需要的数据,那么引擎就不会去主键上去搜索数据了,这就是覆盖索引。

1
select age from user where age = 19;

这条语句就符合覆盖索引的概念。在age的索引树中,我们可以获得我们需要查询的所有字段。

1
select ID,age,enable from user where age = 19;

这条就不符合覆盖索引的概念,需要回表。

这就是为什么在这条SQL语句中的Extra中没有Using index

总结:

辅助索引上已经存在我们需要的数据,不需要回表


回表和覆盖索引
https://johnjoyjzw.github.io/2021/09/04/回表和覆盖索引/
Author
John Joy
Posted on
September 4, 2021
Licensed under