Mysql 索引下推和回表查询是啥?

先来看看sql语句的部分执行流程

  1. Server层:通过优化器选择要使用的索引、将查询条件和索引发送到存储引擎层执行。

  2. 存储引擎层:根据索引扫描(遍历)符合条件的索引记录,然后将索引记录返回给Server层

  3. Server层:拿到过滤后的索引,判断是否需要回表(查询字段是否都存在于索引)。如果索引里没有所有的查询字段,则将索引中的主键们发送到存储引擎层。

    比如索引idx_a_b

    select c from t where a = 5;

    索引中没有c,需要通过主键回表拿到完整数据行,然后获取c

  4. 存储引擎层:根据主键,查询聚簇索引,得到完整的数据行,返回给Server层

  5. Server层:做最终过滤出查询的字段,返回数据。

什么是回表?

上述过程第三、四步。

存储引擎层第一次过滤索引后,Server层再次将过滤后的索引发送给存储引擎层,过滤出对应的数据行(每一条索引记录,都需要通过主键到聚簇索引中查询)。这个过程就是回表。

什么是索引下推?

这是 Mysql 5.6+ 的新特性,一般作用于联合索引上。

抽象来讲 就是将where条件的部分判断下推到存储引擎层,在索引遍历过程中提前过滤,减少回表次数是次数!

举个栗子:

联合索引:idx_name_age

sql:SELECT * FROM users WHERE name like '张%' AND age = 18;

假设mysql 5.5 版本,没有索引下推机制。

此时的执行流程

  1. Server层选择索引idx_name_age、将条件和索引发送给引擎层
  2. 引擎层根据name like '张%'条件、过滤出500条联合索引,返回到Server层
  3. Server层将索引对应主键发送到引擎层 回表500次
  4. 引擎层根据主键查询到一条聚簇索引,返回数据行。
  5. Server层对数据行 判断是否满足 age = 18,如果满足,加入到返回的集合中。
  6. Server层返回数据集。
看看mysql 5.6+版本,有索引下推机制。

此时的执行流程

  1. Server层选择索引idx_name_age、将条件和索引发送给引擎层。逻辑不变
  2. 引擎层判断name like '张%'的同时,会额外判断索引中age =18、最终过滤出50条联合索引,返回到Server层。 逻辑变了
  3. Server层将索引对应主键发送到引擎层 回表50次逻辑不变
  4. 引擎层根据主键查询到一条聚簇索引,返回数据行。逻辑不变
  5. Server层直接返回数据集。变了

可以看到,将本来Server层判断age = 18的逻辑,下推到了引擎层。

扩展

SQL:SELECT * FROM users WHERE name = '张三' AND age > 18;

此时引擎层可以直接通过索引扫描数据,无需下推。因为此时的检索条件在索引中是有序的

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐