Yihui’s Blog

请详细描述 MySQL 的 B+ 树中查询数据的全过程

日期:2026-07-05 难度:困难 标签:#面试 #八股 #MySQL #B+树 #索引 #VIP

一句话答案

MySQL 使用 B+ 树索引查询时,会从根节点开始按键值比较定位到子节点,逐层向下直到叶子节点;叶子节点中找到目标索引记录后,如果是聚簇索引可直接拿到整行,如果是二级索引通常还要拿主键回表。

面试口语版

以 InnoDB 为例,索引页按 B+ 树组织。查询某个 key 时,先从根页开始,在页内通过目录和二分查找找到应该进入的子节点指针,然后读取下一层索引页,重复这个过程,直到叶子节点。聚簇索引叶子节点存完整行,所以主键查询到叶子节点就能拿到数据。二级索引叶子节点存的是索引列和主键值,如果查询字段不被覆盖,就要用主键再到聚簇索引查一次,也就是回表。范围查询则定位到起始叶子节点后,沿着叶子节点的双向链表继续扫描。

原理拆解

flowchart TD
  A[根节点页] --> B[比较 key 定位子节点]
  B --> C[中间节点页]
  C --> D[继续比较定位]
  D --> E[叶子节点页]
  E --> F{索引类型}
  F -- 聚簇索引 --> G[直接读取完整行]
  F -- 二级索引 --> H[拿到主键值]
  H --> I[回表查聚簇索引]
  I --> J[读取完整行]

范围查询:

flowchart LR
  A[定位范围起点叶子页] --> B[扫描当前叶子页]
  B --> C[沿叶子节点链表向后]
  C --> D[直到超过范围结束]

关键细节

  • B+ 树非叶子节点只存键值和页指针,叶子节点存真实索引记录。
  • InnoDB 页默认大小通常是 16KB,一个页能存很多 key,所以树高通常较低。
  • 查询层数越低,磁盘 IO 次数越少。
  • 主键查询走聚簇索引,二级索引查询可能回表。
  • 范围查询依赖叶子节点有序链表。
  • Buffer Pool 命中时不一定发生磁盘 IO。

面试官追问

  1. B+ 树根节点、中间节点、叶子节点分别存什么?
  2. 为什么 B+ 树高度通常很低?
  3. 范围查询为什么适合 B+ 树?
  4. 二级索引查询为什么可能查两棵 B+ 树?
  5. Buffer Pool 对索引查询有什么影响?

常见错误说法

错误说法问题更好的说法
每次查询都要从磁盘读整棵树忽略缓存Buffer Pool 命中时可直接读内存页
二级索引叶子节点存整行错误InnoDB 二级索引叶子节点存主键值
B+ 树只适合等值查询错误叶子节点有序链表很适合范围查询

学习清单

  • 能画出根节点、中间节点、叶子节点。
  • 分别复述主键查询和二级索引查询。
  • 解释范围查询如何沿叶子链表扫描。
维护与整理 · Yihui在 GitHub 上编辑

继续阅读

浏览全部文章

SQL与NoSQL有什么区别?MySQL和MongoDB如何选型?实际项目中如何选择?

日期:2026-09-27 标签:#面试 #MySQL #数据库 难度:简单 来源:牛面 MySQL 题库 答案说明:独立整理(站内题目标记为 VIP,未读取会员答案) 一句话答案 MySQL与MongoDB的主要差异在数据模型、事务边界、查询方式和模式演化;按业务访问模式和一致性需求选型。 面试口语版(约 60…

阅读全文