MySQL 索引深度解析:B+ 树、覆盖索引与慢查询治理
B+ 树为什么适合磁盘
InnoDB 聚簇索引是一棵 B+ 树:
- 非叶子节点只存键,扇出大,树高低(通常 3~4 层千万行)
- 叶子节点链表相连,范围扫描
BETWEEN、ORDER BY友好 - 数据行存在主键叶子页;二级索引叶子存 主键值,需要回表
聚簇索引 vs 二级索引
| 类型 | 叶子存储 |
|---|---|
| PRIMARY KEY | 完整行 |
| 二级索引 | 索引列 + 主键 |
查询 WHERE user_id = 1 若只有 user_id 二级索引,流程:
- 在二级索引树定位
user_id=1的叶子 - 拿到主键 id 列表
- 回表到聚簇索引取完整行(除非覆盖索引)
覆盖索引(Covering Index)
若查询列全部在索引里,无需回表:
-- 索引 idx_user_status (user_id, status, created_at)
SELECT status, created_at
FROM orders
WHERE user_id = 100 AND status = 1;
EXPLAIN 里 Extra: Using index 即覆盖索引,线上性能提升非常明显。
联合索引与最左前缀
索引 (a, b, c) 可高效支持:
aa, ba, b, c
不能跳过左侧列单独用 b(除非优化器 index skip scan,版本相关)。
设计原则:等值过滤列放前,范围列放后;区分度高的列靠前。
EXPLAIN 要看什么
EXPLAIN SELECT * FROM posts WHERE slug = 'hello'\G
关注:
type:ALL全表扫描要警惕,目标ref/range/constkey:实际使用的索引rows:估算扫描行数Extra:Using filesort/Using temporary考虑改写 SQL 或加索引
慢查询治理流程
- 开启
slow_query_log,阈值 1s(按业务调) pt-query-digest或云监控聚合 TOP SQLEXPLAIN+ 必要时SHOW PROFILE- 加索引 / 改写 / 拆表 / 缓存,避免盲目加索引(写放大、占空间)
小结
索引不是「列上加个 KEY」了事,而是 用 B+ 树换磁盘 IO。理解回表与覆盖索引后,联合索引顺序才能一次设计对,少踩「建了索引仍然慢」的坑。
相关阅读
- Node.js API 的 JWT 认证:签发、校验与安全清单2026-05-14
本站评论 (0)
- 暂无评论,来说第一句吧。