MySQL索引面试问题梳理
本文系统剖析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树的数据存储方式导致单页索引键减少,可能增加树高。
三、联合索引失效场景
见我的博客《MySQL索引失效12种场景:用架构分层思想优化实战》