MySQL 索引
索引的定义
MySQL 索引是帮助数据库高效获取数据的排好序的数据结构,核心作用是:
- 将无序的原始数据,通过特定结构组织成'可快速检索'的形式;
- 避免全表扫描(Full Table Scan),直接定位目标数据的物理位置;
- 类比:书籍的目录(通过目录快速找到章节,而非逐页翻找)。
索引的核心价值与代价
| 核心价值 | 核心代价 |
|---|---|
| 极快的查询速度(SELECT) | 写入性能下降(INSERT/UPDATE/DELETE) |
| 减少磁盘 I/O 次数 | 占用额外磁盘空间(索引文件) |
| 排序/分组操作加速 | 索引维护成本(数据变更需更新索引) |
关键结论:索引是'空间换时间'的设计——用额外的磁盘空间和写入开销,换取查询性能的大幅提升。
MySQL 索引的底层数据结构:为什么是 B+ 树?
MySQL 主流存储引擎(InnoDB/MyISAM)的索引底层均基于B+ 树实现,而非数组、链表、哈希表或红黑树。要理解这一点,需先对比常见数据结构的优劣,再拆解 B+ 树的设计精髓,尤其要搞懂:为什么 MySQL 选择 B+ 树而非 B 树?
常见数据结构对比(为什么不选它们?)
| 数据结构 | 优点 | 缺点(不适合 MySQL 索引) |
|---|---|---|
| 数组(有序) | 二分查找效率高(O(logn)) | 插入/删除需移动大量数据,维护成本高 |
| 链表 | 插入/删除便捷 | 查询需遍历(O(n)),效率极低 |
| 哈希表 | 等值查询极致快(O(1)) | 不支持范围查询(如>、<、BETWEEN);无序 |
| 红黑树(二叉树) | 插入/查询均为 O(logn) | 树高过高(百万数据需 20 层),磁盘 I/O 次数多 |
| B 树(多路平衡树) | 树高更低 | 数据分散在所有节点,范围查询需回溯;叶子节点无链表 |
问题:为什么用 B+ 树而不用 B 树?
B 树和 B+ 树同属'多路平衡树',但 B+ 树针对数据库的'磁盘 I/O 特性'和'业务查询场景'做了关键优化,二者的核心差异及选择 B+ 树的原因如下:
数据存储位置:B+ 树数据仅在叶子节点,B 树分散在所有节点
- B 树结构:每个节点(包括非叶子节点、叶子节点)都存储'索引值 + 实际数据',导致非叶子节点能容纳的索引项数量大幅减少,树高更高; 示例:16KB 的磁盘页,B 树节点若存储数据,仅能存 10 个索引项,百万数据需 5 层树;
- B+ 树结构:非叶子节点仅存储'索引值 + 子节点指针',不存实际数据,可容纳更多索引项,树高显著降低; 示例:同样 16KB 磁盘页,B+ 树非叶子节点可存 1000 个索引项,百万数据仅需 3 层树。
核心优势:树高越低,磁盘 I/O 次数越少(每次访问节点需一次 I/O),查询效率呈指数级提升。
范围查询:B+ 树叶子节点链表,B 树需回溯父节点
- B 树范围查询:若要查询
id BETWEEN 100 AND 200,找到 100 后需回溯父节点,再遍历子节点,多次 I/O 且逻辑复杂;

