为什么 MySQL选择使用 B+树作为索引结构?

  • 后端
  • MySQL
大约 3 分钟全民制作人ikun

为什么 MySQL选择使用 B+树作为索引结构?

B+树的基本结构

B+树是一种多路平衡查找树,它由B树演变而来。在B+树中:

  • 所有数据记录都存储在叶子节点上
  • 非叶子节点只存储键值和指针,不存储数据
  • 所有叶子节点通过指针连接成一个单向链表
  • 树的高度通常较低,一般为2-4层

与其他数据结构的比较

相比B树

  • B+树所有数据都在叶子节点,非叶子节点不存储数据,更适合磁盘存储
  • B+树叶子节点相互链接,更有利于范围查询和全表扫描
  • B+树非叶子节点只存键值,在相同内存下可以存储更多索引条目

相比红黑树

  • 红黑树是二叉树,树高较高,可能导致更多的磁盘IO
  • B+树是多路树,降低树高,减少磁盘IO次数
  • 对于大数据量,红黑树的查询效率明显低于B+树

相比哈希表

  • 哈希表不支持范围查询和排序操作
  • 哈希表在数据量大时性能可能下降(哈希冲突)
  • B+树支持范围查询和有序访问

磁盘IO优化

  • B+树的高扇出性(一个节点可以有多个子节点)使树的高度较低
  • 树高降低意味着查询时磁盘IO次数减少
  • MySQL页大小通常为16KB,配合B+树结构可以在一次IO中读取更多索引

顺序访问性能

  • B+树叶子节点通过链表相连,顺序访问只需要沿着链表遍历
  • 范围查询效率高,只需找到范围起点,然后沿链表顺序访问
  • ORDER BY、GROUP BY等操作因此能高效执行

空间利用率

  • B+树非叶子节点不存储数据,只存储键值和指针
  • 在相同内存条件下,B+树能容纳更多索引条目
  • 节点填充率高,空间利用效率好

缓存友好性

  • B+树结构符合磁盘预读原理
  • 适合局部性原理和磁盘预读,提高缓存命中率
  • 结构紧凑,数据页可以有效利用CPU缓存

并发控制

  • B+树结构便于实现锁粒度优化
  • 非叶子节点修改概率低,减少锁冲突
  • 适合InnoDB的MVCC(多版本并发控制)机制

实际性能表现

  • 在常见数据量(千万级以上)下查询复杂度稳定在O(log n)
  • 单次查询通常只需2-4次磁盘IO
  • 范围查询性能优异,适合OLTP业务场景

总结

特性维度B+树优势对比其他数据结构
磁盘IO效率树高低(2-4层),减少IO次数远优于红黑树,AVL树等二叉树结构
范围查询支持叶子节点链表结构,支持高效范围访问优于B树和哈希索引
空间利用率非叶节点不存数据,相同空间存储更多索引优于B树
缓存友好性符合磁盘预读原理,提高缓存命中率优于随机访问的结构
并发控制便于实现锁粒度优化,减少锁冲突更适合数据库事务处理
插入删除效率平衡树结构,插入删除后仍保持平衡优于不平衡的树结构
有序性天然保持键值有序优于哈希表等无序结构
查询稳定性最坏情况性能有保障,O(log n)复杂度优于哈希表(最坏O(n))

MySQL选择B+树作为索引结构是综合考虑了上述多方面因素的结果。这种数据结构在磁盘环境下能够提供出色的查询性能、良好的空间利用率以及对范围查询的支持,使其成为关系型数据库索引的理想选择。