MySQL 索引面试题
1. 聚簇索引与非聚簇索引的区别
【题目】
聚集索引(聚簇索引)与非聚集索引(非聚簇索引)的区别?
【参考答案】
| 特性 | 聚簇索引 | 非聚簇索引 |
|---|---|---|
| 叶子节点 | 直接存储整行数据 | 存储主键值(指向数据行的指针) |
| 物理顺序 | 索引顺序 ≈ 数据物理存储顺序 | 索引顺序与物理存储无关 |
| 数量限制 | 每表只能 1 个 | 每表可有多个 |
| 查找速度 | ⚡ 主键查询极快(一次 B+ 树查找) | 🐢 需要回表(二次查找) |
回表过程:非聚簇索引查主键值 → 聚簇索引查完整行数据
覆盖索引 如果查询的列全部在非聚簇索引中(即索引已经”覆盖”了查询),则无需回表。这是覆盖索引(Covering Index)的优化思路。
【延伸追问】
- 什么是覆盖索引?如何避免回表?
- 为什么 InnoDB 表建议使用自增主键?
【易错坑点】
- ❌ 非聚簇索引不一定需要回表(覆盖索引满足查询时)
- ❌ MyISAM 的索引全部是非聚簇索引,即使主键索引也需回表
- ❌ 混淆 InnoDB 和 MyISAM 的索引组织方式
2. 索引创建时机
【题目】
什么是 MySQL 的索引,以及何时应创建索引?
【参考答案】
索引是基于 B+ 树的数据结构,以空间换时间加快数据检索。
✅ 应创建索引的场景:
- 经常出现在 WHERE 条件中的列
- JOIN 连接的列
- ORDER BY 和 GROUP BY 中涉及的列
- 区分度高的列(选择性越高的列越优先)
❌ 不适合索引的场景:
- 数据量小的表(全表扫描更快)
- 频繁更新的列(索引维护成本高)
- 区分度低的列(如性别、状态字段)
索引的代价 索引以空间换时间,但每增加一个索引都会拖慢 INSERT / UPDATE / DELETE。生产环境建议控制在 5~8 个索引以内。
【延伸追问】
- 联合索引的最左前缀原则是什么?
- 如何通过 EXPLAIN 判断索引是否生效?(关注 ype、key、Extra 字段)
【易错坑点】
- ❌ 加了索引不等于查询会走索引(优化器可能选择全表扫描,比如回表代价太高时)
- ❌ 为所有列建索引(严重降低写入性能)
- ❌ 忽略联合索引的顺序导致索引失效
关联文档
- MySQL 基础知识面试题 — 基础概念题
- MySQL 事务与锁面试题 — 事务与锁