MySQL 之所以选择 B+树 作为索引结构,而不是其他数据结构(如 B-树、哈希索引、红黑树等),主要是因为 B+树在数据库索引场景下具有更好的查询性能、磁盘 IO 友好性和范围查询效率。以下是 B+树作为 MySQL 索引的关键优势:
1️⃣ B+树 vs. B-树
| 特性 | B+树 | B-树 |
|---|---|---|
| 叶子节点存储数据 | ✅ 仅叶子节点存数据 | ❌ 所有节点都存数据 |
| 范围查询 | ✅ 叶子节点间有链表,查询快 | ❌ 范围查询较慢 |
| 磁盘读取效率 | ✅ 只存索引,单节点存储更多 | ❌ 数据和索引混存,占用更多空间 |
| 树的高度 | ✅ 更矮(减少磁盘 IO) | ❌ 更高(增加磁盘 IO) |
B+树的主要优化点
-
非叶子节点仅存储索引,不存储数据
- B+树的 非叶子节点 只存储 键值(索引),不会存放实际数据,这样一个节点能存 更多索引,从而 减少树的高度,提高查找效率。
-
磁盘访问次数更少(减少IO操作)
- 数据库通常采用 磁盘存储,一次磁盘读取是按 页 读取(一般 16KB)。B+树每个非叶子节点可存 大量索引,从而降低树的高度,使得查询时需要的磁盘 IO 次数更少,速度更快。
-
范围查询更快(叶子节点有链表)
- B-树 的范围查询必须回溯树结构,而 B+树 的 叶子节点通过双向链表连接,可以直接进行 顺序扫描,范围查询的性能远高于 B-树。
2️⃣ B+树 vs. 哈希索引
| 特性 | B+树 | 哈希索引 |
|---|---|---|
| 支持范围查询 | ✅ 快速 | ❌ 只能精准匹配 |
| 支持排序 | ✅ 是有序结构 | ❌ 无序 |
| 适用场景 | ✅ 适合大多数查询 | ❌ 仅适用于等值查询 |
| 冲突处理 | ✅ 无冲突 | ❌ 需要处理哈希冲突 |
为什么不用哈希索引?
- 哈希索引适用于 等值查询(如
WHERE id = 100),但 无法进行范围查询(如WHERE id BETWEEN 50 AND 100)。 - MySQL ORDER BY 需要有序索引,而哈希索引是无序的,无法提供高效的排序查询。
3️⃣ B+树 vs. 红黑树
| 特性 | B+树 | 红黑树 |
|---|---|---|
| 适用场景 | ✅ 适合磁盘存储 | ❌ 适合内存存储 |
| 节点存储量 | ✅ 一个节点存多个索引 | ❌ 一个节点只存一个索引 |
| 磁盘访问次数 | ✅ 少,IO 更少 | ❌ 多,IO 更高 |
为什么不用红黑树?
- 红黑树适用于内存索引(如 HashMap),但 MySQL 的索引需要 磁盘存储,红黑树的单个节点只能存一个索引,会导致树的高度很高,查询时磁盘 IO 太多,性能低下。
- B+树的非叶子节点存更多索引,能保持树的高度较低,从而减少磁盘 IO,查询更快。
4️⃣ 低树高:减少磁盘 IO,提高查询效率
数据库索引的查询性能很大程度上取决于磁盘IO次数。
假设:
- 一个 B+树的节点大小是 16KB(MySQL 默认的 InnoDB 数据页大小)。
- 每个索引占 8 字节,则一个节点可存放 16KB / 8B = 2048 个索引。
- 假设有 10 亿条数据,如果使用 B+树索引:
- 第一层(根节点) 存 2048 个索引,管理 2048² ≈ 400 万 条记录。
- 第二层(中间节点) 管理 2048³ ≈ 8 亿 条记录。
- 第三层(叶子节点) 才存储实际数据。
只需 3 次磁盘 IO 就能找到数据! 而如果使用红黑树,树的高度可能高达 30+ 层,需要 30+ 次磁盘 IO,查询速度大大降低。
总结
为什么 MySQL 选择 B+树作为索引?
-
磁盘 IO 更少(降低查询时间)
- B+树的非叶子节点不存数据,可以存更多索引,树的高度更低,查询时磁盘 IO 更少,速度更快。
-
支持范围查询 & 排序
- 叶子节点通过 链表连接,范围查询(
BETWEEN)和排序(ORDER BY)效率极高,而哈希索引无法支持范围查询。
- 叶子节点通过 链表连接,范围查询(
-
提高查询性能
- B+树的索引结构可以高效查找、批量读取,特别适用于 MySQL 海量数据的索引优化。
-
适合磁盘存储
- 红黑树适用于内存,而 B+树适用于磁盘存储,减少了磁盘访问次数,提高了性能。
结论:B+树是 MySQL 查询效率最优 的索引结构,在磁盘 IO、范围查询、排序等方面全面优于 B-树、哈希索引和红黑树。
599




被折叠的 条评论
为什么被折叠?



