浅谈MySQL的回表和覆盖索引

 MySQL比较常见的三种存储引擎:InnoDB、MyISAM、Memory。

这三种引擎实现索引的方式不太相同,InnoDB、MyISAM使用的是B+树,Memory使用的是哈希索引。虽然InnoDB、MyISAM都使用的是B+树,但两者还是不完全相同的。InnoDB中,主键索引的B+树叶子节点存储的是整行数据MyISAM主键索引的B+树叶子节点存储的是整行数据所在内存中的地址

回表&覆盖索引

        用一个简单的例子来说明。创建一张表emp,如下图。 

浅谈MySQL的回表和覆盖索引

    给ename创建普通索引,这张表一共有两个所有,如下图。

浅谈MySQL的回表和覆盖索引

下面是两个不同的sql语句的执行计划:

浅谈MySQL的回表和覆盖索引

两条sql语句的区别就是一条select *另外一个是select empno。

先解释一下select * from emp where e.ename='test';先是根据ename列的索引B+树,找到叶子节点上存储的主键值,然后根据主键的索引B+树,查找整行的数据。整个这个操作叫做回表。

再来说一下select empno from emp where e.ename='test';先是根据ename列的索引B+树,找到叶子节点上存储的主键值,由于显示的就是empno,不需要再去主键的索引B+树去查找了,这种情况叫做覆盖索引。

通过上面两个例子,可以看出来回表操作需要遍历两次B+树,增加了IO次数。所以能用覆盖索引就尽量用覆盖索引。

简单补充一下,上图的执行计划中的Extra 可能会出现using whereusing indexusing index;using whereusing index contionnull。如果出现了using index,就表示覆盖索引