InnoDB 为什么使用 B+ 树索引?
未标记
考查重点:树高、页访问与范围扫描。B+树非叶页分支多使树较矮,叶页有序连接便于范围扫描;同时支持点查与增删改,但仍有页分裂与维护成本
本题目录
参考答案
核心回答
InnoDB 使用 B+ 树组织普通索引,主要是为了兼顾少量页访问完成定位、有序范围扫描,以及数据持续增删改这几类需求。
- 多路分支让树比较矮。 索引以页组织,非叶子页主要保存索引键和子页定位信息,单页能指向许多子页。相比逐层只有两个分支的树,定位同样多的数据通常需要经过更少的层级,减少潜在的磁盘读取。
- 叶子页按键有序,适合范围查询。 找到范围起点后,可以沿叶子页链接继续扫描,不必为范围里的每条记录重新从根查找;索引顺序满足查询条件时,也有利于排序和分组。
- 同一种结构能支撑点查与范围查。 聚簇索引的叶子页保存行记录,二级索引的叶子记录保存索引列与对应主键;需要完整行时,再按主键访问聚簇索引。
它的优势来自页组织和访问模式的配合,不能简单概括成“时间复杂度最低”。插入、删除仍有维护页、分裂或合并的成本;树高也不等于实际磁盘读取次数,因为索引页可能已经在 Buffer Pool 中。
展开说明
为什么数据库更关心访问多少页
数据库不会为了比较一个索引键就单独从磁盘取几个字节,而是以页为单位管理数据。InnoDB 默认索引页大小为 16 KB,实例初始化时可以采用其他受支持的页大小。因此,一个页里能容纳多少索引项、一次读取后能排除多大的搜索范围,直接影响定位成本。
B+ 树把行记录或二级索引记录集中在叶子层。非叶子页不装入完整行,能把空间用于更多索引键和子页定位信息,形成较大的扇出。这里的比较条件是相近的页大小与键宽;不能脱离记录大小、填充程度,断言所有表都只有三层。
根页和常用内部页通常更容易被缓存。一次查询即使经过三层,也可能只有最后的叶子页需要从磁盘加载,甚至全部命中缓存。树高描述结构上的搜索路径,物理 I/O 还要结合缓存命中和实际访问的页判断。
范围查询为什么方便
范围扫描可以分成两段:先沿索引树定位第一条符合条件的记录,再沿叶子层继续读取。图中箭头表示这两段的访问顺序。
flowchart TD
T[沿索引树定位范围起点] --> A[起始叶页 A:10、20]
A -->|沿有序叶页链接扫描| B[下一叶页 B:30、40]查 id = 20,从根定位到叶页 A,再在页内找到记录。查 15 <= id <= 40,先定位到第一条符合条件的记录 20,再沿叶页链接读取 30、40,直到超过上界或读完范围。这种顺序扫描避免了每条记录都重新走一次根到叶的路径。
叶页按索引键有序连接,指的是逻辑顺序,不保证这些页在磁盘上物理连续。联合索引还要按完整的键顺序理解;是否能利用索引完成排序,要看过滤条件、排序列和索引定义,不能只凭“用了 B+ 树”判断。
为什么不直接用哈希表、红黑树或 B 树
- 哈希表适合等值定位,但哈希值不保留原键的大小顺序,难以直接支持有序范围扫描。范围条件可以通过扫描等其他方式处理,只是无法利用哈希定位获得同样的范围检索优势。
- 红黑树、
AVL树解决了普通二叉搜索树可能退化的问题,但二叉分支限制了扇出。把这类结构直接用于大规模页存储,通常需要更多层级;它们在内存容器中的价值,与数据库普通索引的选择并不矛盾。 - **
B 树**也是多路平衡树,也能做范围查询;区别在于它的内部节点也可保存数据,点查可能提前命中。B+ 树让内部页集中承担导航,把记录放在有序叶子层,更便于组织页式范围扫描。不能据此断言每次B+ 树点查都比B 树快。
选择 B+ 树是在常见数据库负载下取得综合收益,不是说其他结构没有用途。
聚簇索引与二级索引的叶子里分别是什么
聚簇索引的叶子记录保存行数据,通常以主键组织。二级索引还需要保存自己的索引列,例如 idx_status_time(status, created_at) 的叶子记录包含 status、created_at 和主键值,并非只有一个主键地址。
查询所需列被二级索引覆盖时,可以利用覆盖索引减少回表;需要其他列时,再用取得的主键到聚簇索引查找。因此,主键过宽也会增大二级索引占用,影响单页能容纳的记录数与缓存利用。
常见追问
不建主键,还会有聚簇索引吗?
会。没有显式主键时,InnoDB 会选择第一个所有键列均为 NOT NULL 的唯一索引;没有合适索引时,再生成隐藏的行标识组织聚簇索引。不能把“不声明主键”等同于“表没有聚簇组织”。
B+ 树是不是写入也没有代价?
不是。写入需要找到相应页并维护索引项,页空间不足时可能分裂,删除后也可能触发页合并;二级索引越多,需要维护的结构通常也越多。是否值得增加索引,要结合查询收益、写入负载和存储成本判断。
参考资料
- 国内:JavaGuide:MySQL 索引详解:借鉴哈希、二叉树、B 树与 B+ 树的比较,解释正文中按访问模式选择索引,并采用聚簇、二级索引说明叶子记录与回表。
- 国内:JavaGuide:树结构详解:参考面试复盘中二叉搜索树、平衡树与多路树的对照,区分正文中保持平衡与提高页内扇出的作用。
- 国内:小林 coding:为什么 MySQL 采用 B+ 树作为索引?:采用 B+ 树先定位起点再沿叶子扫描的过程,解释正文中点查与范围查询的数例。
- 国内:小林 coding:揭开 Buffer Pool 的面纱:借鉴数据读取与缓存页的说明,解释正文中树层级为何不能直接换算成磁盘读取次数。
- 国外:MySQL 8.4:The Physical Structure of an InnoDB Index:依据索引页、默认页大小及页空间维护,解释正文中扇出、页分裂与合并的存储基础。
- 国外:MySQL 8.4:Clustered and Secondary Indexes:依据聚簇索引选择及二级索引携带主键的规则,说明正文中叶子存储、回表和主键宽度的影响。
- 国外:MySQL 8.4:Buffer Pool:关于表与索引数据在内存中缓存的说明,为区分结构上的页访问与实际磁盘 I/O 提供依据。
相关面经
42 篇快手
Agent 开发工程师MySQL InnoDB 索引底层为什么使用 B+ 树
新东方
Java开发工程师(AI Agent方向)索引的底层结构是什么?为什么要用B+树索引结构?聚簇索引和非聚簇索引的区别是什么?
字节跳动
后端开发MySQL 的引擎是什么?底层数据结构?为什么不用 B 树?索引一定生效吗?
字节跳动
AI 应用客户端开发实习生B+树做索引为什么快
公司未注明
后端开发工程师展开剩余 37 篇面经
水滴公司
AI 全栈工程师索引用的是 B+ 树,为什么用 B+ 树,用别的比如哈希、B 树行不行?
百度
AI智能体算法MySQL 的 B+Tree 索引为什么适合范围查询?
蚂蚁集团
AI Agent 应用工程师MySQL索引优先选用B+树的原因,对比B树的区别
字节跳动
Agent2.1 为什么 MySQL 索引使用 B+ 树,而不是其他树结构?
快手
全栈实习生讲一下MySQL的B+树的优点有哪些?
网易云音乐
全栈开发 / 后端开发实习水滴
AI全栈拼多多、荣耀、立元科技、得物、华橙
B+如何实现范围查询?
多益网络
软件开发工程师数据库索引具体使用的是哪种数据结构?为什么使用B+树?
字节跳动
Agent 开发为什么数据库索引常用 B+ 树,而不是二叉搜索树、红黑树或 B 树?
腾讯
后端开发工程师得物
Java 开发工程师为什么使用B+树,不使用二叉树、红黑树、B树这些?
美团
AI 全栈开发工程师MySQL索引底层为什么用B+树?和B树有什么区别
蚂蚁集团
数据库索引结构
蚂蚁集团
索引的底层数据结构是什么?B+ 树为何查询高效?
蚂蚁集团
B+树结构,为什么要用B+树,有什么优点
阿里巴巴(淘天)
AI 应用开发工程师B + 树为什么可以提升 MySQL 查询 IO 效率
水滴
质量保障工程师(AI)数据库索引是什么数据结构,为什么用b+树
中科创达
后端开发工程师(AI / RAG 方向)MySQL 索引底层为什么使用 B+ 树?
美团
后端开发工程师知乎
全栈开发工程师B+树优点
去哪儿
AI 应用开发工程师InnoDB为什么用B+树
字节跳动
Agent 开发工程师了解过MySQL吗?用的是什么数据结构存储?为什么?B+树的优点是什么?
哔哩哔哩(B站)
后端开发工程师(游戏广告)B+树
小红书、百度
请你介绍一下MySQL中B+树索引特点?
字节跳动
Agent 测评mysql的索引为什么快,底层什么原理
滴滴
AI Agent 后端开发数据库索引的底层结构是什么?什么时候会失效?
字节跳动
AI 应用开发工程师快手
后端开发工程师MySQL索引用了什么数据结构,相比其他数据结构有什么好处?
阿里巴巴
后端开发MySQL的索引结构是什么?为什么用B+树而 不是B树或哈希表?
蚂蚁集团
Agent 应用开发工程师mysql的数据结构,讲讲B+树
腾讯
后端开发工程师(AI)MySQL的InnoDB的索引结构是什么?B➕树的优点是什么?
蚂蚁国际
AI 应用 / Agent 开发MySQL的索引结构你了解吗?为什么是B+树,而不是红黑树、平衡二叉树或者哈希结构?
快手
后端开发a. MySQL 的索引和索引失效的情况
京东
AI 后端 / Agent 开发滴滴
Agent 开发工程师Mysql为什么使用B+树
字节跳动
后端开发工程师InnoDB B+ 树的结构和特点是什么?












