如何阅读案例
标准结构
每个案例都遵循统一的五段式叙事流:
痛点 → 分析 → 方案 → 对比 → 避坑1. 痛点(场景描述)
用真实的业务背景开场,让你立刻代入。例如:
电商订单列表页,用户翻到第 10 万页时,接口耗时从 50ms 飙升到 3 秒。
2. 分析(为什么慢)
给出常见的"问题写法"(bad.sql),然后用 EXPLAIN 分析瓶颈所在。我们会关注 EXPLAIN 的几个关键字段:
| 字段 | 关注点 |
|---|---|
type | ALL = 全表扫描,最该优化的信号 |
key | NULL 表示没用上索引 |
rows | 预估扫描行数,越大越慢 |
Extra | Using filesort(文件排序)、Using temporary(临时表)是性能杀手 |
3. 方案(优化原理)
给出优化后的写法(good.sql),讲清楚为什么这样写更快。核心原理无非这几类:
- 加索引 / 改索引:让查询走索引而非全表扫描
- 改写 SQL:换一种等价但更高效的写法
- 利用新特性:8.0 的降序索引、Hash Join、CTE 等
- 架构调整:汇总表、冷热分离等
4. 对比(量化效果)
给出优化前后的 EXPLAIN 对比表,用数字说话:
| 优化前 | 优化后 | |
|---|---|---|
| type | ALL | ref |
| rows | 980,000 | 12 |
| Extra | Using filesort | Using index |
| 耗时 | 1.2s | 2ms |
5. 避坑(注意事项)
每个方案都有适用边界和副作用,我们会明确标注:
注意
延迟关联方案要求排序字段上有索引,且结果集顺序不能变。如果你的分页有动态排序需求,需要额外处理。
本地复现
每个案例的文档右侧都有对应的 SQL 文件路径,例如:
sql/cases/01-deep-pagination/
├── schema.sql # 建表
├── seed.sql # 造数据
├── bad.sql # 问题 SQL
├── good.sql # 优化 SQL
└── expected/ # 参考的 EXPLAIN 结果运行方式见 快速开始。
难度标记
| 标记 | 含义 |
|---|---|
| ⭐ | 入门:理解索引基础即可 |
| ⭐⭐ | 进阶:需要理解执行计划 |
| ⭐⭐⭐ | 高级:涉及架构设计或版本特性 |
版本标记
| 标记 | 含义 |
|---|---|
| 5.7 & 8.0 | 两个版本行为一致 |
| 5.7+ | 5.7 起可用 |
| 8.0+ | 仅 8.0 可用(利用新特性) |
案例中会标注版本差异,你可以用 --ver 5.7 和 --ver 8.0 对比执行效果。