mysql中的回表操作

什么是回表查询?

一般情况下是:先到普通索引上定位主键值,再到聚集索引上定位行记录,它的性能较扫一遍索引树低。

具体解释:

我们自己建的索引不管是单列索引还是联合索引,都称为普通索引,主键索引是聚簇索引,也就是索引的叶子节点存的是整个单条记录的所有字段值。每个普通索引就对应着一颗独立的索引B+树,索引 B+ 树的节点仅仅包含了索引里的几个字段的值以及主键值。当你执行一条sql语句时,需要从两个b+索引中去取数据。

在什么情况会出现回表操作?

举个例子:

tbla,b,c三个字段,其中 a是主键,b上建了索引,然后编写sql语句SELECT * FROM tbl WHERE a=1这样不会产生回表,因为所有的数据在a的索引树中均能找到;

如果是SELECT * FROM tbl WHERE b=1这样就会产生回表,因为where条件是b字段,那么会去b的索引树里查找数据,但b的索引里面只有a,b两个字段的值,没有c,那么这个查询为了取到c字段,就要取出主键a的值,然后去a的索引树去找c字段的数据。查了两个索引树,就出现了回表操作。

什么是索引覆盖?

简单说就是, 索引列+主键 包含 SELECT 到 FROM之间查询的列 。就是索引覆盖。可以不用去进行回表操作。

为什么设置了命中了索引但还是造成了全表扫描

就是虽然命中了索引,但在叶子节点查询到记录后还要大量的回表,优化器认为不如直接去扫描全表。

Published by

风君子

独自遨游何稽首 揭天掀地慰生平