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
再查完整行
拿主键 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 步在 name_idx 中定位
步骤 1
在 name_idx 中定位
步骤 2
拿到主键 id=10
步骤 3
回到 PRIMARY 取完整行
步骤 4
覆盖索引对比