外观
一句话答案
B+ 树非叶节点只存 key,叶子节点存数据且双向链表相连,3 层可存亿级数据,范围查询高效。
核心要点
InnoDB 还有:
1. 自适应哈希索引(Adaptive Hash Index,AHI)
- InnoDB 自动(非用户手动创建)为频繁访问的索引页建立哈希索引
- 当某个 B+ 树索引被频繁等值查询时,InnoDB 自动在内存中建立哈希索引,使等值查询 O(1)
- 完全由 InnoDB 自动维护,用户无法手动创建
- 可用
innodb_adaptive_hash_index开关控制
2. 全文索引(FULLTEXT)
- InnoDB 5.6+ 支持,基于倒排索引(与 ES 类似)
- 适合全文搜索,不适合普通 WHERE 条件
B+ 树 vs 哈希索引对比:
| 维度 | B+ 树 | 哈希索引 |
|---|---|---|
| 等值查询 | O(log N) | O(1),更快 |
| 范围查询 | ✅ 支持(叶子链表) | ❌ 不支持(哈希打散了顺序) |
| 排序 | ✅ 支持(叶子有序) | ❌ 不支持 |
| 前缀匹配 | ✅ 支持 | ❌ 不支持 |
| 哈希冲突 | 无此问题 | 有,冲突多时退化 |
| 存储 | 磁盘 + 内存 | 通常只在内存(Memory 引擎) |
什么时候用哈希索引:
- 确定只做等值查询(
=或IN),不需要范围、排序、前缀 - 使用 Memory 引擎的临时表
- InnoDB 的 AHI 会自动处理高频等值查询的优化,无需手动
追问与易错
追问方向:
- 为什么不用哈希索引?(不支持范围查询/排序)
- 一个 B+ 树节点能存多少 key?(16KB 页,bigint 8B + 指针 6B → 约 1170 个)
- 主键用自增 ID 还是 UUID?为什么?(自增顺序插入不分裂,UUID 随机写导致页分裂)
易错点:
- ❌ "B+ 树查找一定要走到叶子"——对的,但非聚簇索引找到主键后还要回表
- ❌ 混淆 B 树和 B+ 树——B 树非叶子也存数据
💡 记忆锚点
B+ 树像一本字典:目录页(非叶子节点)只写拼音不写释义,翻到正文页(叶子节点)才有完整解释,正文页之间用页码顺序串起来(双向链表)。所以查单词要翻到正文,查一段范围直接沿页码顺序扫过去。三层目录就能索引两千万词条,每次查找最多翻三页(三次磁盘 IO)。