InnoDB 的 B+ 树、聚簇与非聚簇索引、回表如何工作?

考查重点:索引叶子内容与回表路径。B+树按键定位,InnoDB聚簇叶子存行,二级叶子存索引列和主键;查询缺少所需列时凭主键回聚簇索引取行

本题目录

参考答案

核心回答

以 MySQL 8.4 的 InnoDB 常规索引为例,可以把它理解为:B+ 树负责有序定位,聚簇索引保存行记录,二级索引通过主键关联到行记录,需要其他列时再回表。

  • B+ 树:非叶子节点主要保存用于导航的键和子页指针,索引记录放在叶子页,叶子页按键顺序连接。等值查找沿树向下定位;范围查找先找到起点,再沿叶子页访问。
  • 聚簇索引:叶子层保存行记录。有显式主键时,InnoDB 用主键组织聚簇索引;一张表的数据围绕这一棵聚簇索引组织。
  • 普通二级索引:叶子记录包含二级索引列和对应主键值。根据二级条件找到主键后,如果还需要索引中没有的列,就用主键再查聚簇索引,这一步称为回表。

因此,二级索引叶子不只是保存主键,也不是直接保存行所在的磁盘地址。二级索引与聚簇索引的区别,在于叶子记录承载什么,以及后续怎样找到行。

用一次查询说明过程

假设用户表以 id 为主键,另有二级索引 (name,age),一条二级记录可以包含 name、age、id。

查询某个 name 对应用户的地址时,通常先在二级树中定位 name,拿到匹配记录的 id,再逐个通过聚簇树取出地址。name 不唯一时,可能找到多条记录并产生多次回表。

如果查询只需要 name、age、id,这些值已经能从二级索引获得,就具备覆盖查询的条件,从取列需求上可以避免回表。覆盖是针对具体查询而言的:同一个索引,对查 id 的请求可能覆盖,对查地址的请求就未必覆盖;实际执行还要看优化器选择和事务读取条件。

索引下推解决的是另一个环节:如果某些条件能在二级记录上判断,可以先过滤掉不符合的项,减少需要回表的记录数。它与覆盖查询不是同一件事。

为什么使用 B+ 树?

数据库按页管理索引。一个内部页可以放很多导航项,形成较大的分支数,让大量记录仍能通过较少层级定位。把业务记录集中在叶子层,也让内部页更紧凑,并方便沿叶子顺序处理范围扫描。

不过,树高不等于每次查询必然发生的磁盘 I/O 次数。部分页可能已在 Buffer Pool 中,范围扫描会涉及多少叶子页、需要多少回表,也会改变成本。不能把“通常树不高”简化成任何查询固定两三次磁盘读取。

叶子页的逻辑相邻也不保证它们在磁盘文件中物理连续,更不能由索引有序推出不写 ORDER BY 的结果顺序承诺。

常见追问

没有显式主键呢? InnoDB 先找第一个所有键列均非空的唯一索引作为聚簇索引;仍没有合适索引时,再生成隐藏行标识来组织聚簇索引。这个内部标识不能直接当作业务表里新增了一个可用主键字段。

唯一二级索引就不用回表吗? 不由“唯一”决定。唯一约束描述键值是否可重复,回表取决于还需要哪些数据,以及具体读取路径。

主键设计为什么影响二级索引? 普通二级记录会携带主键。主键越长,通常会让这些索引项更大,影响页容量、缓存与维护成本;修改主键也会牵连其他索引。

回表是不是一定慢? 少量精确定位的回表可能很合理;若二级条件筛出大量记录,却要取很多索引外字段,成本就可能高。需要结合扫描量、返回量、缓存和实际计划判断,而不是只看用了哪个索引。

参考资料

相关面经

14 篇

水滴公司

AI 全栈工程师
校招秋招一面、二面
查看原面经 →
MySQL 主要是它的索引和它的存储引擎数据结构有什么关系呢?

字节跳动

Agent
秋招一面
查看原面经 →
MySQL 底层索引使用什么数据结构?

公司未注明

测试开发岗
一面、二面、三面
查看原面经 →
MySQL索引底层B+树,什么场景索引会失效,说出至少4种。

美团

AI 后端
校招秋招一面、二面
查看原面经 →
MySQL 聚簇索引和非聚簇索引的叶子节点分别存储什么?

快手

测试开发
一面
查看原面经 →
mysql 知道吗,你可以讲讲你了解的他的索引
展开剩余 9 篇面经

智元机器人、字节跳动

面经合集
查看原面经 →
数据库常见索引实现方式、索引类型、唯一索引和主键索引区别

腾讯

后端开发工程师
实习一面
查看原面经 →
MySQL 这块你了解吗?
简历上写了 B+ 树,能简单介绍一下 B+ 树吗?

字节跳动

AI 应用工程师
一面
查看原面经 →
数据库索引、事务了解吗?
索引的底层原理是什么?

得物

Java 开发工程师
一面
查看原面经 →
索引结构介绍一下。

去哪儿

测试开发工程师
一面
查看原面经 →
索引的原理是什么?
你对MySQL的索引了解有多少(如B+Tree)?

知乎

全栈开发工程师
秋招一面
查看原面经 →
mysql的innodb索引是什么

小鹏

后端开发工程师(AI / Agent 方向)
二面
查看原面经 →
讲一下 InnoDB 索引的原理(B+ 树、聚簇索引/非聚簇索引、回表)?

字节跳动

AI 应用开发工程师
日常实习一面
查看原面经 →
主键索引和普通索引有什么区别?

字节跳动

后端开发工程师
一面
查看原面经 →
了解 InnoDB 的 B+ 树吗?

相关题目

4 题