01 / FLOW三步急诊流程
先定流程,再看病例
所有慢查询都走同一条路。流程本身,就是这节课要教的东西。
① 定位
谁在慢?大屏耗时榜或慢查询日志,拿到 SQL 原文与耗时。
纪律:说不清「慢多少」的,不许进第二步。
纪律:说不清「慢多少」的,不许进第二步。
② 读片
EXPLAIN 上墙。全班按口令读:type → rows → Extra,一人一句,说完诊断。
纪律:诊断必须带依据(「rows 120 万」),不许说「感觉慢」。
纪律:诊断必须带依据(「rows 120 万」),不许说「感觉慢」。
③ 开方验证
改索引或改写 SQL → 再跑一次 EXPLAIN → 前后耗时写进对比卡。
纪律:没有验证的处方不得分——这条写进评分。
纪律:没有验证的处方不得分——这条写进评分。
02 / CASE-1病例一 · 选错地界的索引
三个候选,只有一个建对地方
首页报表 1.84 秒。学生桌上摆着三个候选索引,让执行计划宣判。
SELECT s.name, e.score FROM students s JOIN enrollments e ON s.id = e.student_id WHERE e.term = '2026-秋' AND e.score < 60 ORDER BY e.score;
| 候选 | type | rows | 判决 |
|---|---|---|---|
| A · idx_score (score) | range | 81,920 | 范围列单打独斗:term 的等值过滤沾不上光,扫完还要回表。聊胜于无。 |
| B · idx_term_score (term, score) | range | 213 | ✓ 等值在前、范围在后:term 钉死起点,score 只走一小段,连 ORDER BY 都顺路解决。 |
| C · idx_title (courses.title) | ALL | 1,204,880 | 建在别人家地里:查询里根本没有 title。 |
验证记录:1.84 s → 0.03 s,对比卡上墙。出题点就两个:最左前缀、等值列在前,范围列在后——选错一次,比讲三遍记得牢。
03 / CASE-2病例二 · 索引失灵
索引明明在,key 却是 NULL
idx_created_at 建得好好的,查询却全表扫描。让学生自己找出「手术痕迹」。
-- 病历:YEAR() 把索引列包了起来,优化器不认 SELECT * FROM crawl_events WHERE YEAR(created_at) = 2026; -- ALL · 全表扫 -- 处方:把「算术」换回「范围」,索引立刻认账 SELECT * FROM crawl_events WHERE created_at >= '2026-01-01' AND created_at < '2027-01-01'; -- range · 提速 6 倍
| 写法 | type | rows | 耗时 |
|---|---|---|---|
| YEAR(created_at) = 2026 | ALL | 2,318,442 | 1.92 s |
| created_at 范围写法 | range | 316,204 | 0.31 s |
同病名单(点名让学生对号):对索引列套函数或运算(score + 50 < 90)、隐式类型转换(字符串列拿数字查)、LIKE '%xx' 前导通配符、OR 两侧没有全索引。一句总结:对索引列做手术,索引就罢工。
04 / CASE-3病例三 · 排序之痛
filtering 很快,排序要命
WHERE 明明走了索引,还是慢——Extra 里的 Using filesort 暴露了真凶。
SELECT id, content, created_at FROM crawl_events WHERE student_id = 42 ORDER BY created_at DESC LIMIT 10; -- 处方:排序列进联合索引,filesort 当场消失 CREATE INDEX idx_student_time ON crawl_events (student_id, created_at);
诊断:student_id 走了索引,但捞出来的行要回到服务层再排一次序——「过滤很快,排序要命」。处方验证:建联合索引后 Extra 里的 filesort 消失,LIMIT 10 只摸 10 行。
一句话:WHERE 管过滤,ORDER BY 管顺序——各吃各的索引,一个都不能少。
05 / GAME课堂玩法 · 分组急诊赛
把三个病例,换成你平台的真数据
分组
3–4 人一组,每组一条不同的慢 SQL——从你平台的慢日志里现场挑,别用教材题。
限时
20 分钟走完三步:定位 → 读片 → 开方。处方与前后耗时写进对比卡。
计分
提速倍数 ×60% + 讲得清程度 ×40%。评委随机抽问「为什么」,答不出按玄学处理。
防作弊
处方必须带验证截图——没跑过 EXPLAIN 前后对比的方案,不得分。这条从第一天就宣布。
「没有验证的优化,都是玄学。」
—— 急诊室的铁律:处方后面必须跟一行前后耗时。这也是他们未来在任何公司里活下来的职业习惯。
配套材料 · 第三级慢查询练习集——八条真慢 SQL,附前后耗时答案去拿 →