← [ BACK_TO_NOTES ]

B+Tree 数据库索引

解释 B+Tree 为什么适合关系型数据库索引:高扇出、低树高、叶子有序、范围扫描、页分裂,以及它与 B-Tree、Hash、红黑树的取舍。

#concept #growing #backend #database

[!info] related notes

B+Tree 数据库索引

[!abstract] 一句话定义 B+Tree 是面向外存 Page 访问设计的多叉平衡搜索树:内部节点主要导航,叶子保存最终索引项并按 Key 有序组织。高扇出让树很矮,因此等值查询只需少量 Page 跳转,范围查询还能连续扫描叶子。

为什么数据库关心 Page I/O

CPU comparison: cheap
random storage Page access: much more expensive

数据库优化目标不是只减少比较次数,而是尽量减少从 Root 到 Leaf 的 Page 数量,并让后续访问更连续。

高扇出为什么重要

一个内部 Page 只保存紧凑的:

separator key + child page pointer

所以能容纳大量 Child:

                 [10 | 40 | 80 | ...]
              /       |       |       \
          child     child   child     child
large fan-out
→ low height
→ few Page reads

二叉树每个节点只有两个 Child,面对磁盘 Page 时会更深、随机跳转更多。

内部节点与叶子节点

内部节点

用于选择下一层 Child,不保存完整业务行,从而提高 Fan-out。

叶子节点

保存最终索引项,可能是:

  • Key + 完整行;
  • Key + 主键;
  • Key + Tuple / Row Locator;
  • Key + Included Columns。

具体取决于数据库和索引类型,见 聚簇索引与二级索引。

等值查询

Root Page
→ compare separator keys
→ Internal Page
→ Leaf Page
→ locate key / row reference

Root 和上层 Page 往往长期驻留内存,实际物理 I/O 可能更少,但逻辑访问路径仍存在。

范围查询

叶子按 Key 有序,数据库定位起点后可以向后扫描:

WHERE created_at >= ? AND created_at < ?
ORDER BY created_at
seek first matching leaf entry
→ scan consecutive entries / leaf pages
→ stop at upper bound

这也是 B+Tree 相比 Hash Index 的重要优势。

为什么不是 Hash Index

Hash 适合等值定位,但通常不保留 Key 的全序,因此不自然支持:

  • Range;
  • Prefix Order;
  • ORDER BY;
  • Min / Max;
  • 有序遍历。

某些数据库会为特定场景提供 Hash Index,但通用默认索引仍多使用 B-tree 家族。

为什么不直接用红黑树 / AVL

红黑树和 AVL 适合内存中细粒度节点访问;每个节点只有少量 Child,树高更大。B+Tree 让一个 Page 承载大量 Key,设计目标直接对齐 Block I/O。

B+Tree 与 B-Tree

术语在教材与数据库实现中可能略有差异。稳定理解是:

  • B-tree 家族都是多路平衡树;
  • 数据库常让内部节点偏导航、叶子承载最终索引项;
  • 叶子有序扫描支持范围查询;
  • 具体是否链表连接、哪些值出现在内部节点,应以实现为准。

不要因为命名差异忽略 Page、Fan-out 和范围扫描这三个核心机制。

Insert、Split 与写入成本

目标 Leaf 有空间时直接插入;Page 满时可能:

split page
→ redistribute entries
→ insert separator into parent
→ parent may split recursively

影响:

  • 额外 Page Write;
  • WAL / Redo;
  • Cache 与锁竞争;
  • Fragmentation;
  • 随机 Key 比顺序 Key 更容易打散局部性。

Fill Factor 等参数可用空间换减少未来 Split,但不是越低越好。

B+Tree 不会让所有查询都快

仍然取决于:

  • Query 是否能形成连续 Key Range;
  • 选择性;
  • 是否需要大量回表;
  • 排序和过滤能否利用索引顺序;
  • 统计信息;
  • 写入和维护成本。

“有索引”不等于优化器一定选择它。

面试回答

数据库通常按 Page 做 I/O。B+Tree 的内部节点只放 Key 和 Child Pointer,一个 Page 能容纳很多分支,所以 Fan-out 高、树高低,从 Root 到 Leaf 只需少量 Page 访问;叶子又按 Key 有序,定位起点后可以连续做范围扫描。相比二叉树它更适合块存储,相比 Hash 又支持 Range 和 Order,因此成为关系型数据库通用索引结构。

掌握标准

  • Page I/O 与高 Fan-out;
  • 内部节点和叶子的分工;
  • 等值查询与范围扫描路径;
  • 与 Hash、红黑树的取舍;
  • Page Split 和写放大;
  • 为什么有 B+Tree 索引仍可能不使用。
创建于 2026/9/2 更新于 2026/9/4
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本