贝利信息

SQL 覆盖索引如何减少回表?

日期:2026-01-19 00:00 / 作者:舞夢輝影
覆盖索引能避免回表,是因为查询所需所有字段均可直接从索引叶子节点获取,无需再通过主键回聚簇索引查找整行数据;回表指二级索引查到主键后,需二次B+树搜索获取非索引列,开销大。

覆盖索引能避免回表,是因为它让查询所需的所有字段都直接从索引中获取,无需再回到主键索引(聚簇索引)的叶子节点去查数据行。

什么是回表?

在 InnoDB 中,二级索引的叶子节点只存储索引列 +

对应主键值。当查询语句用到了二级索引,但 SELECT 列或 WHERE 条件中包含非索引列 时,MySQL 就得拿着查到的主键值,再回到聚簇索引里把整行数据捞出来——这个过程就叫“回表”。它多了一次 B+ 树搜索,开销明显。

覆盖索引怎么做到不回表?

只要 SQL 中所有用到的列(包括 SELECT、WHERE、ORDER BY、GROUP BY 涉及的列)都包含在同一个索引里,优化器就会走该索引,并且直接从索引叶子节点返回结果,跳过回表。

如何判断是否用了覆盖索引?

EXPLAIN 结果中的 Extra 列:

设计覆盖索引的小建议

覆盖索引不是越多越好,要权衡维护成本和查询频次: