【MySQL】回表 索引下推

一、回表

众所周知使用innodb的表可以存在多个二级索引,但只能有一个主键索引。这主键索引满足下列要求:

  • 当存在主键,索引值就是主键
  • 当主键不存在,但存在唯一索引,那么索引值就是该唯一索引
  • 当既不存在主键,也不存在唯一索引,那么就自动生成rowid所谓索引值

主键索引索引值存储在b+树的叶子节点上,同时他还带着对应的行数据。
而二级索引索引值带的数据则是主键索引的索引值。
假设你的主键索引值是自增的id,你还设了了一个二级索引,并通过sql语句使用该二级索引查询,此时MySQL会在该索引上查询得到主键id,然后再通过主键id去查询,这就叫做回表。

二、索引下推

回表有什么坏处呢?
回表会增加查询的步骤、降低查询效率,试想你创建了一个(name,age)的二级索引。当你通过name和age查询时,会先在二级索引上根据name得到主键并回表,回表后还要在主键索引上查询age。

可以发现回表直接导致了二级索引上的age没有被使用到,当使用索引下推后就不存在这种情况了。MySQL是默认开启索引下推的。手动开关代码如下:

set optimizer_switch='index_condition_pushdown=off'
set optimizer_switch='index_condition_pushdown=on'

使用索引下推后会优先在索引上进行查询过滤,使用explain查询会发现:

  • 当Extra的值为Using index condition; 说明你查询的字段全部在索引上完成了过滤操作,回表时会根据主键直接得到对应的行数据。
  • 当Extra的值为Using where时,可能你的查询字段没有设置索引,这时会直接在主键索引上查询,效率低下。
  • 当Extra的值为Using index condition; Using where时,说明你查询的一部分部分字段有索引,另一部分没有索引,当有索引的字段完成查询时回表,并不会立马返回数据,而是还要再全表查询那些没有索引的字段。

你可能感兴趣的:(——MySQL)