为什么 MySQL 选择 B+Tree 而不是 B-Tree 或红黑树?最左前缀原则的根本原因是什么?从数据结构讲起。

一、索引的本质——排序的数据结构

  • 1.1 索引 = 预排序 + 快速查找
  • 1.2 没有索引时——全表扫描
  • 1.3 有索引时——二分查找的变种

二、为什么是 B+Tree

  • 2.1 哈希表——等值查询快,范围查询不行
  • 2.2 二叉搜索树——高度太高,磁盘 IO 多
  • 2.3 B-Tree——非叶子节点也存数据,范围查询仍需中序遍历
  • 2.4 B+Tree——数据只存叶子节点,叶子节点双向链表连接

三、B+Tree 的结构

  • 3.1 页(Page)——InnoDB 的最小存储单元,默认 16KB
  • 3.2 非叶子节点——只存键值 + 子节点指针
  • 3.3 叶子节点——存完整数据,双向链表串联
  • 3.4 为什么 B+Tree 的高度很低——高扇出

四、聚簇索引与二级索引

  • 4.1 聚簇索引——叶子节点存完整行数据(主键索引)
  • 4.2 二级索引——叶子节点存主键值
  • 4.3 回表——二级索引找到主键,再回聚簇索引查完整数据
  • 4.4 覆盖索引——避免回表

五、最左前缀原则

  • 5.1 联合索引的 B+Tree 结构——按字段顺序排序
  • 5.2 为什么 (a, b, c) 索引,WHERE b = ? 用不了
  • 5.3 索引下推(ICP)——5.6 的优化

六、索引失效的场景

  • 6.1 LIKE '%xxx'——前缀模糊匹配
  • 6.2 函数/计算——WHERE DATE(create_time) = '2024-01-01'
  • 6.3 类型隐式转换——WHERE phone = 13800138000
  • 6.4 OR 条件——非索引列参与 OR

七、总结

  • B+Tree 是为磁盘 IO 优化的数据结构
  • 索引设计的本质是”排序字段的选择”