首页 >> 基础教程

mysql为什么用 B+ 树而不用 B 树呢?

      MySQL(尤其是其默认存储引擎InnoDB)选择 B+树 而非 B树 作为索引的核心数据结构,是经过深度权衡后的结果。核心原因围绕 磁盘I/O效率范围查询性能 和 与数据库特性的契合度 展开。以下是具体分析:

1. 更优的磁盘 I/O 性能(核心优势)

  1. B+树非叶子节点不存储数据

    1. B+树的内部节点仅存储键值和子节点指针,而 B树的每个节点都存储键值+数据指针(甚至直接存储行数据)。
      影响

      1. 相同磁盘页大小(如16KB)下,B+树的非叶子节点能存储更多键值(扇出更大)。

      2. 树高显著降低(3~4层即可支持千万级数据),查询时磁盘I/O次数更少(减少随机I/O)。

  2. 示例

    1. 假设一个节点大小16KB,键值占10B,指针占6B:

      1. B+树:一个非叶子节点可存 16KB / (10B+6B) ≈ 1000 个键值。

      2. B树:若数据指针占8B,则只能存 16KB / (10B+6B+8B) ≈ 666 个键值。
        B+树的树高更低,查询路径更短!

2. 范围查询的极致优化

    B+树叶子节点形成有序链表
    B+树的所有叶子节点通过双向指针串联,天然支持顺序扫描

  1. 范围查询(如WHERE id BETWEEN 100 AND 200

    1. 定位到id=100的叶子节点。

    2. 沿链表顺序遍历,直到id>200全程顺序I/O

  2. B树的缺陷

    1. 数据分散在各层节点,范围查询需回溯父节点+深度遍历,产生大量随机I/O

3. 查询稳定性(可预测性)

  • B+树:所有查询必须到达叶子节点
    无论查哪条数据,路径长度严格等于树高(性能稳定)。

  • B树:数据可能出现在中间节点
    若目标数据在根节点附近,查询更快;若在叶子节点,则需完整遍历。
    影响:B树的查询时间波动大,不利于数据库优化器预判代价。

4. 全表扫描效率

  • B+树:遍历叶子节点链表即可完成全表扫描(顺序I/O)。

  • B树:需中序遍历整棵树(递归访问左/中/右节点),随机I/O多,速度慢

5. 与InnoDB存储设计的深度契合

  • 聚集索引(Clustered Index)
    InnoDB的表数据直接存储在B+树叶子节点(按主键排序),形成"索引即数据"的结构。

    • 二级索引(Secondary Index)
      叶子节点存储主键值(非数据指针),通过主键回表查询。
      B+树的"所有数据在叶子节点"特性完美支持此设计

    • 主键索引:叶子节点=行数据。

    • 二级索引:叶子节点=主键值 → 减少冗余存储。

对比总结:B+树 vs B树在MySQL中的表现

特性B树B+树B+树优势
节点数据所有节点存键值+数据指针非叶节点仅存键值+指针;叶子节点存数据非叶节点更小 → 树高更低
范围查询需回溯中序遍历(随机I/O)叶子节点链表顺序扫描(顺序I/O)速度提升10倍+
查询稳定性不稳定(数据可能在任意层)稳定(必须到叶子节点)优化器代价估算更准确
全表扫描中序遍历(随机I/O)遍历叶子链表(顺序I/O)避免大量随机I/O
缓存利用率节点含数据 → 缓存键值更少非叶节点纯键值 → 更多节点缓存热数据常驻内存,减少磁盘访问
适配InnoDB难以实现"索引即数据"天然支持聚集索引+二级索引架构深度契合数据库引


为什么B树没有被完全淘汰?

虽然B+树在磁盘数据库中占绝对优势,但B树仍有场景:

  1. 内存数据库(如Redis):数据在内存中,无需优化磁盘I/O,B树的单点查询可能更快。

  2. 特定文件系统(如HFS+):元数据索引场景中B树仍有应用。
    但在MySQL这类基于磁盘的关系型数据库中,B+树是索引的最优解。

总结:MySQL选择B+树,本质是以磁盘I/O最小化为核心,通过降低树高顺序访问优化稳定查询路径三大设计,完美适配数据库的高并发、大数据量、范围查询等核心需求。


最新文章
mysql分页问题2025-08-04
千万数据先insert和先建索引哪个快2025-08-04
MySQL 中大小表关联查询如何优化2025-08-04
sql技巧-每个班年龄排前两名的人2025-08-03
MySQL 导致 cpu 飙升的话,要怎么处理呢?2025-07-29
MySQL 中为千万级大表添加字段2025-07-29
mysql中百万级别以上的数据如何删除2025-07-29
分库分表带来的问题2025-07-29
mysql中常用的分库分表中间件有哪些2025-07-29
mysql不停机扩容2025-07-29
备案号:蜀ICP备2023042032号-1