前言
最近做了几个比较大数据量的项目,用的数据库也都是mysql,因此想来借这个机会说一说mysql查询时候会接触到的一大特性—回表。
索引
谈及回表,一定绕不开索引的概念,一些基本的概念在这里都不细说了,如果有不清楚的读者可以点击下面的传送门
MySQL索引
其中聚集索引和非聚集索引是要关注的重点!后面会提及到
聚集索引
上一节的链接文章中介绍了聚合索引,而回表则是因为其的以下特性:聚合索引记录的是该行记录所有的值,而普通索引仅仅记录用于建立索引的值及对应聚合索引的值
下面用一个网上找的例子来说明一下
我们先假设有这么一张表
t(id PK, name KEY, sex, flag); 即有id,name,sex,flag四个字段,其中id是主键(也就是聚合索引),name是普通索引。
而表中有以下四条记录:
1, shenjian, m, A
3, zhangsan, m, A
5, lisi, m, A
9, wangwu, f, B
我们来看看以下sql语句是怎么执行的,select * from t where name=‘lisi’;
不难发现,实际上是先通过普通索引定位到lisi和5,然后再用5去聚合索引里面查找到整条记录,这个就是mysql的回表。
覆盖索引
现在清楚了什么是回表,那么如何避免回表呢,很简单,就是通过覆盖索引,我们看一看以下sql(仍然是针对上面的实例表)
我们可以发现,根据前面的理论,很明显下面那条是触发回表的,而上面的没触发,解释之后发现上下的extra不一样,查询mysql官网可以看到
explain的输出结果Extra字段为Using index时,能够触发索引覆盖。那么我们修改一下索引,建立name和sex的联合索引,然后再解析第二句sql
可以发现触发了索引覆盖。
结论
其实明白了回表之后想要避免回表,建立索引覆盖是一件非常简单的事情,但是往往很多人不知道回表这个概念,写这篇文章也仅仅是记录一下在mysql学习过程中的一个小小的积累而已。