【DB_MySQL】MySQL索引原理及底层数据结构
MySQL索引原理及底层数据结构
1 B+树索引数据结构
InnoDB索引底层采用**B+平衡树**,所有叶子节点到根高度一致,一般3‑4层;每个节点对应磁盘页,默认16KB。
| 节点类型 | 存储内容 |
|---|---|
| 非叶子节点(根/分支) | 只存**索引键 + 子节点指针**,不存真实行数据,方便更多索引加载进内存,减少磁盘IO |
| 叶子节点 | 存储真实数据;叶子节点之间通过**双向链表相连,支持范围查询** |
IO特点:树高3‑4层,查询最多3‑4次磁盘IO。
2 聚簇索引 & MyISAM非聚簇索引
- **InnoDB 聚簇索引(主键索引)**
- 叶子节点直接存储**整行完整数据**,表数据本身就是B+树的叶子节点。
- 一张表**只能有1个聚簇索引**:
- 有主键:主键作为聚簇索引;
- 无主键:选唯一非空索引;
- 都没有:MySQL自动生成隐藏rowid作为聚簇索引。
- **InnoDB二级索引(普通索引、联合索引)**
- 叶子节点存:**索引键 + 主键值**,**不存完整行数据**。
- ⭐回表:查到主键后,再去聚簇索引B+树根据主键读取完整行,多一次B+树查找。
- **MyISAM(非聚簇)**
主键、二级索引叶子都存**数据行的磁盘地址**,没有回表概念。 - **联合索引(复合索引)**
- 多个字段组合构建索引,排序规则:先按第一个字段排序,第一个相同再按第二个字段排序。
- 查询遵循**最左前缀匹配原则**。
3 B+树存储容量估算(面试常问)
磁盘页默认16KB,页头固定开销约120字节。
- 非叶子节点:每条
索引键+指针约10B,单页可存:16\*1024 / 10 ≈ 1600个索引项 - 三层B+树:第一层根、第二层分支,可支持叶子节点总数 ≈
1600 \* 1600 = 256万 - 叶子节点,单行100字节:单页存放约160行
- 理论总容量:
256万 \* 160 ≈ 41亿行数据所以千万级表,3层B+树就足够。
4 B+树示意图

5 索引核心总结(背诵要点)
- B+树非叶子节点只存索引键和指针,不存行数据;叶子节点双向链表,高效支持范围查询。
- InnoDB聚簇索引叶子存放整行记录;二级索引叶子存放主键,需要回表拿完整数据。
- 联合索引遵守最左前缀匹配。
- 索引本质**空间换查询时间**;索引不是越多越好,索引会增加INSERT/UPDATE/DELETE写操作维护成本。
高频面试题:
Q:为什么InnoDB表必须要有主键?
A:InnoDB是聚簇索引,数据存储依赖聚簇索引;没有主键MySQL会自动生成隐藏rowid,性能不如自定义主键,不推荐。
Q:二级索引查询流程?
A:走二级索引B+树找到主键 → 通过主键去聚簇索引B+树查询完整行(回表)。
Q:B+树为什么适合数据库索引?
1)树的高度很低,磁盘IO次数少;
2)非叶子节点不存数据,可以缓存大量索引到内存;
3)叶子双向链表,范围查询非常友好。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 咱村唯一架构师!