本文系统剖析MySQL索引的核心机制:
- 索引分类全景图:详解聚簇/非聚簇索引的逻辑差异与物理存储特点
- B+树的统治性优势:通过对比Hash/B树揭示InnoDB的底层选择逻辑
一、索引分类的常见困惑解析
1. 按物理存储分类
类型 |
存储内容 |
数量限制 |
特点 |
代表引擎 |
聚簇索引 |
数据行本身 |
每表1个 |
数据即索引 |
InnoDB主键 |
非聚簇索引 |
主键引用 |
多个 |
需回表查询 |
MyISAM/InnoDB二级索引 |
2. 按逻辑功能分类
索引类型 |
键约束 |
NULL值处理 |
数量限制 |
是否聚簇 |
典型创建语句 |
适用场景 |
主键索引 |
唯一且非空 |
禁止NULL |
每表1个 |
是(InnoDB) |
ALTER TABLE t ADD PRIMARY KEY(id) |
行唯一标识,快速定位 |
唯一索引 |
唯一但允许NULL |
允许NULL |
多个 |
否 |
CREATE UNIQUE INDEX idx_name ON t(name) |
防止重复值,如手机号 |
普通索引 |
允许重复值 |
允许NULL |
多个 |
否 |
CREATE INDEX idx_age ON t(age) |
加速高频查询条件 |
全文索引 |
无唯一性约束 |
允许NULL |
多个 |
否 |
ALTER TABLE t ADD FULLTEXT(content) |
文本内容搜索 |
空间索引 |
无唯一性约束 |
禁止NULL |
多个 |
否 |
ALTER TABLE t ADD SPATIAL INDEX(pt) |
GIS地理坐标查询 |
3. 按数据结构分类
类型 |
数据结构 |
支持引擎 |
适用场景 |
B+Tree索引 |
平衡多路树 |
InnoDB/MyISAM |
99%场景 |
Hash索引 |
哈希表 |
Memory引擎 |
精确匹配 |
R-Tree索引 |
空间树 |
MyISAM |
地理数据 |
Full-text索引 |
倒排索引 |
InnoDB/MyISAM |
文本搜索 |
二、InnoDB为何选择B+树作为索引结构?
1.常见索引数据结构对比
在数据库系统中,不同的索引数据结构适用于不同的查询场景。以下是几种主流索引结构的对比:
数据结构 |
查询复杂度 |
范围查询 |
磁盘I/O效率 |
适用场景 |
代表存储引擎 |
Hash索引 |
O(1) |
❌ 不支持 |
❌ 随机I/O高 |
精确匹配(如=、IN) |
Memory引擎 |
二叉搜索树 |
O(log n) |
✅ 支持 |
❌ 树高不可控 |
内存型数据 |
较少使用 |
AVL/红黑树 |
O(log n) |
✅ 支持 |
❌ 树高仍较高 |
内存型数据 |
较少使用 |
B树 |
O(log n) |
✅ 支持 |
✅ 较优 |
磁盘存储 |
MongoDB(B树变种) |
B+树 |
O(log n) |
✅ 支持 |
✅ 最优 |
磁盘存储(范围查询) |
InnoDB、MyISAM |
关键结论
- Hash索引:仅适合精确查询,无法支持范围查询(如>、<、BETWEEN)。
- 二叉/平衡树:树高不可控,导致磁盘I/O次数增加,不适合大规模数据存储。
- B树:相比B+树,非叶子节点存储数据,导致单页存储的索引键减少,树高可能更高。
- B+树:InnoDB的默认选择,具有更稳定的查询性能、更低树高、更优的范围查询支持。
2. B+树的核心优势
(1) 更低的树高,减少磁盘I/O
- B+树的非叶子节点仅存储索引键(不存储数据),因此单页可容纳更多索引项,树高更低。
(2) 天然支持高效范围查询
- B+树的所有数据均存储在叶子节点,并按顺序形成链表,范围查询只需遍历叶子节点。
(3) 更适合磁盘存储
- B+树的叶子节点形成有序链表,减少随机I/O,提高顺序读取性能(适合机械硬盘)。
- B树的节点存储数据,可能导致更多的随机I/O。
(4) 更高的缓存命中率
- 非叶子节点仅存储索引键,可缓存更多索引结构,减少磁盘访问。
3. InnoDB为何不选择Hash/B树?
对比项 |
B+树 |
Hash索引 |
B树 |
范围查询 |
✅ 高效 |
❌ 不支持 |
✅ 支持但效率较低 |
磁盘I/O |
✅ 顺序读取优化 |
❌ 随机I/O高 |
✅ 一般 |
树高控制 |
✅ 最优 |
❌ 不适用 |
⚠️ 比B+树略高 |
缓存友好 |
✅ 非叶子节点可缓存 |
❌ 无优化 |
⚠️ 数据分散 |
InnoDB的选择逻辑
- OLTP(在线事务处理) 需要大量范围查询(如分页、排序),B+树最合适。
- 机械硬盘时代,B+树的顺序I/O优势明显(即使SSD时代仍受益)。
- B树的数据存储方式导致单页索引键减少,可能增加树高。