"回表查询"是 数据库索引使用中的一个概念 ,尤其常见于 MySQL InnoDB 存储引擎。
1️⃣ 回表查询的定义
回表查询(Index Lookup + Table Access / Bookmark Lookup)
指查询时使用了 非覆盖索引(non-covering index),索引本身没有包含查询需要的全部列,需要通过索引找到主键或行指针,然后再回到聚簇索引(或者数据表)去读取完整行数据的过程。
简单来说:
- 先在索引中找到匹配的键值和对应的行指针(主键)。
- 再根据主键去 表(叶子节点) 找完整的行数据。
2️⃣ 举例说明
假设有一张表 user:
sql
CREATE TABLE user (
id INT PRIMARY KEY,
name VARCHAR(20),
age INT,
INDEX idx_name(name)
);
- idx_name 索引只包含
name和id(因为是二级索引,InnoDB 二级索引里存的是索引列 + 主键)。 - 查询:
sql
SELECT age FROM user WHERE name = 'Alice';
-
索引
idx_name里有name='Alice'对应的id=101。 -
但是我们要查询的列是
age,索引里没有。 -
回表步骤:
- 在
idx_name索引中找到name='Alice'的id=101。 - 再用
id=101去聚簇索引(表)中找到age列的值。
- 在
-
这个额外的访问表的过程,就是 回表查询。
3️⃣ 回表查询的特点
-
触发条件:非覆盖索引、查询列不在索引中。
-
开销:会多一次访问表(磁盘 I/O 或 Buffer Pool)。
-
优化方式:
-
覆盖索引:在索引里包含查询的所有列。
sqlCREATE INDEX idx_name_age ON user(name, age);这样查询
SELECT age FROM user WHERE name='Alice';就不需要回表。 -
尽量使用主键查询,避免二级索引回表。
-
查询时只选索引列,减少回表。
-
💡 总结一句话:
回表查询就是:先用二级索引找到主键,再用主键去表里获取完整行数据的过程。