D
MySQL 高级后端面试专题 / 索引与查询路径 / SELECT * FROM user WHERE name = 'Tom' 为什么会回表?

MySQL 高级后端面试专题/索引与查询路径

二级索引、聚簇索引、回表、覆盖索引。

运行环境:MySQL 8.0
问题Lab A · 索引与查询

SELECT * FROM user WHERE name = 'Tom' 为什么会回表?

面试官想考什么

你是否真正理解 InnoDB 二级索引和聚簇索引的查询路径,而不是只会背“回表”这个词。

30 秒答案摘要

二级索引先按 name 找到 Tom,但叶子只带主键 id=10。SELECT * 需要整行,所以再用 id=10 去 PRIMARY 聚簇索引取完整行;只查 id,name 时索引已覆盖,无需回表。

1在 name_idx 中定位
2拿到主键 id=10
3回到 PRIMARY 取完整行
4覆盖索引对比

二级索引 B+Tree(name_idx)

键:name,值:主键 id

...
...
...
...
...
Leo
id=3
Mike
id=7
Tom
id=10
Tony
id=12
Zoe
id=15
回表:
拿主键 id=10
再查完整行

聚簇索引 B+Tree(PRIMARY)

键:主键 id,值:整行数据

...
...
...
...
...
id=8
Mike 16 ...
id=10
Tom 18 ...
id=11
Jerry 20 ...
id=12
Tony 22 ...
...

覆盖索引(示例)

SELECT id, name FROM user WHERE name = 'Tom'
在 name_idx 定位到 (name='Tom', id=10)已经包含所需字段直接返回,无需回表
类比:图书馆找书
目录卡片(二级索引)
找到页码(拿到主键 id)
翻到正文页面(聚簇索引取整行)
当前进度:1 / 共 4
步骤 1
在 name_idx 中定位
步骤 2
拿到主键 id=10
步骤 3
回到 PRIMARY 取完整行
步骤 4
覆盖索引对比