← 返回题目列表

为什么 B+ 树这么矮?一棵三层 B+ 树能存多少数据?

高频 中等 第 5 / 25 题 更新于 2026/07/28
B+树磁盘IO扇出树高

简化版

B+ 树矮,是因为扇出(一个节点的孩子数)极大——内部节点只存关键字(几字节),一个 16KB 的磁盘页能装上千个,所以一层就能分出上千路。以 InnoDB 默认参数估算:内部节点一页约存 1170 个索引项,叶子一页约存 16 行,三层 B+ 树 ≈ 1170 × 1170 × 16 ≈ 2000 万行。因为树只有 34 层,查一行数据最多 34 次磁盘 IO。

详细版

核心公式:数据量 ≈ 扇出^(树高-1) × 每叶子行数。

以 MySQL InnoDB 为例的经典估算(默认页大小 16KB):

  • 内部节点:只存「关键字 + 页指针」。假设主键为 bigint(8 字节)+ 页号指针(6 字节)= 14 字节/项,一页可存 16 × 1024 / 14 ≈ 1170 个 → 扇出 ≈ 1170
  • 叶子节点:存整行数据。假设一行约 1KB,一页可存 16 / 1 ≈ 16 行。

据此算树高与容量:

树高容量估算一次查询 IO
2 层(1 内部 + 叶子)1170 × 16 ≈ 1.8 万行2 次
3 层1170 × 1170 × 16 ≈ 2000 万行3 次
4 层1170³ × 16 ≈ 数百亿行4 次

这些是估算量级,随行大小、主键类型变化,但「3 层存千万级、4 层存百亿级」的结论是稳定的。

完整版教学

一、树高由「扇出」决定

一棵树能装 n 个数据、扇出为 f,那么树高 ≈ logₓn(以 f 为底)。扇出越大,同样的 n 树越矮。B+ 树把扇出做到了上千,所以 1170³ ≈ 16 亿 个内部路标只要 3 层——树自然极矮。这和二叉树(扇出 2,2³⁰ ≈ 10 亿 要 30 层)形成鲜明对比。

二、为什么 B+ 树扇出能这么大

扇出 = 一个节点能装多少个「关键字 + 指针」。B+ 树的内部节点只存关键字和指针、不存数据,每一项非常小(十几字节)。一个 16KB 的磁盘页就能塞下上千个,于是扇出上千。

反观 B 树:内部节点还要存数据,每一项大得多,同样一页装不了几个,扇出小、树就高。所以「内部节点不存数据」直接决定了 B+ 树的高扇出、矮树高——这是 B+ 树设计的精髓。

三、算一遍「三层存 2000 万」

用 InnoDB 默认参数走一遍(记住这是经典面试题):

  1. 叶子层:一页 16KB,一行约 1KB,一页存 16 行。
  2. 倒数第二层(内部):一页存 1170 个「主键+指针」,每个指针指向一个叶子页 → 这一层一个节点能管 1170 个叶子页。
  3. 根层(内部):同样 1170 个指针,每个指向下一层的一个内部节点。

于是:

根(1个节点,1170 指针)
  → 1170 个内部节点,每个 1170 指针
    → 1170 × 1170 个叶子页,每页 16 行
= 1170 × 1170 × 16 ≈ 2190 万行

所以「一棵 3 层 B+ 树约存 2000 万行」。

四、为什么实际 IO 比树高还少

树高 3 意味着最多 3 次磁盘 IO,但实际往往更少:

  • 根节点常驻内存:根节点被访问最频繁,数据库会把它缓存在内存(Buffer Pool),访问不产生磁盘 IO。
  • 内部节点大多也被缓存:内部节点数量少(一层才 1170 个)、访问频繁,大部分能缓存。
  • 所以查一行数据,真正的磁盘 IO 常常只有 1 次(读那个叶子页),其余都命中内存。

这就是为什么 InnoDB 单表几千万行,主键查询依然极快。

五、这对建表的启示

理解 B+ 树高度,能解释一些实践建议:

  • 主键要短:主键越小(如用 int/bigint 而非长字符串/UUID),内部节点一页能存的索引项越多、扇出越大、树越矮。这也是「不建议用长字符串或随机 UUID 做主键」的一个原因。
  • 行不要太大:单行越小,叶子页能存的行越多,同样树高能覆盖更多数据。

六、常见误区与追问

考点正确口径
页大小常见 16KB 页能容纳大量 key 和指针
扇出内部节点孩子数很大,树高很低
IO一次下降通常对应少量页访问
fanout ≈ 1000
3 levels: root + internal + leaf
capacity ≈ 1000 * 1000 * leafRecords

B+ 树矮不是因为数据少,而是因为一个节点能分出很多路。

  • 误区:B+ 树三层只能存几千条数据。 三层的容量按扇出相乘,扇出上百上千时可容纳千万级记录。
  • 误区:树高等于查询一定发生的磁盘 IO 次数。 根页和上层页常驻内存,实际磁盘 IO 往往少于逻辑树高。
  • 误区:内部节点存整行数据更好。 内部节点越小扇出越高,树越矮;B+ 树内部节点只存 key 和指针。
  • 追问:为什么页大小会影响树高? 页越大可放的 key 和指针越多,扇出越大,所需层数越少。
  • 追问:三层 B+ 树如何估算容量? 用内部节点扇出逐层相乘,再乘叶子页能放的记录数,做数量级估算即可。
  • 追问:这对主键设计有什么启示? 主键越短,内部节点能放更多 key,扇出更大,索引更紧凑。

七、加强记忆

B+ 树矮,是因为内部节点只存关键字、扇出极大(16KB 页存约 1170 项)。容量 ≈ 扇出^(树高-1) × 每叶子行数。InnoDB 经典估算:3 层 ≈ 1170 × 1170 × 16 ≈ 2000 万行,4 层达百亿级;查一行最多 3~4 次 IO,且根和内部节点常驻内存,实际磁盘 IO 常只有 1 次。启示:主键要短、行不要太大,让扇出更大、树更矮。