MySQL 回表
什么是回表?
简单来说就是数据库根据索引(非主键)找到了指定的记录所在行后,还需要根据索引上保存的主键 ID 再次到数据块里获取数据。
table-access-by-index-rowid
「回表」一般就是指执行计划里显示的 「TABLE ACCESS BY INDEX ROWID」。
再例如,虽然只查询索引里的列,但是需要回表过滤掉其他行。
在 InnoDB 里,索引 B+ Tree 的叶子节点存储了整行数据的是主键索引,也被称之为聚簇索引。而索引 B+ Tree 的叶子节点存储了主键的值的是非主键索引,也被称之为非聚簇索引。
如何避免回表
将需要的字段放在索引中去,查询的时候就能避免回表。
科普时间——覆盖索引
覆盖索引(covering index)指一个查询语句的执行只用从索引中就能够取得,不必从数据表中读取。也可以称之为实现了索引覆盖。当一条查询语句符合覆盖索引条件时,MySQL 只需要通过索引就可以返回查询所需要的数据,这样避免了查到索引后再返回表操作,减少 I/O 提高效率。例如:
表 covering_index_sample
中有一个联合索引 idx_key1_key2(key1,key2)
当我们通过SQL语句:
select key2 from covering_index_sample where key1 = 'keytest';
进行查询的时候,就可以通过覆盖索引查询,无需回表。
本作品采用《CC 协议》,转载必须注明作者和本文链接
能用图解决的我就不说话!
全文扫描才叫回表吗?以前面试问过好像说只要查询就是回表,用索引也是回表,我也懵逼
@jamesZhao 回表是只有在InnoDB存储引擎才会有的,全文扫描和回表是两个概念,全文扫描是没有走索引。 只要查询就是回表这种说法不全面 select * from table_1 where index_a=1 (index_a是索引) 这样是会走回表的。select index_a from table_1 where index_a=1 这样不会走回表(叫覆盖索引,就是你要查询的select的值也是你的where 条件索引值)。
@ZShawn 嗯明白面试官那样说我也不好反驳