慢查询急诊案例集

三个真实病例:一个选错索引地界,一个索引失灵,一个排序之痛。 每例都走同一条急诊流程——定位、读片、开方、验证。SQL 与数字都可直接投屏。

流程 · 三步急诊 素材 · 只读副本 课堂 · 分组急诊赛
01 / FLOW三步急诊流程

先定流程,再看病例

所有慢查询都走同一条路。流程本身,就是这节课要教的东西。

① 定位
谁在慢?大屏耗时榜或慢查询日志,拿到 SQL 原文与耗时。
纪律:说不清「慢多少」的,不许进第二步。
② 读片
EXPLAIN 上墙。全班按口令读:type → rows → Extra,一人一句,说完诊断。
纪律:诊断必须带依据(「rows 120 万」),不许说「感觉慢」。
③ 开方验证
改索引或改写 SQL → 再跑一次 EXPLAIN → 前后耗时写进对比卡。
纪律:没有验证的处方不得分——这条写进评分。
02 / CASE-1病例一 · 选错地界的索引

三个候选,只有一个建对地方

首页报表 1.84 秒。学生桌上摆着三个候选索引,让执行计划宣判。

triage.sql · 首页报表 1.84 s
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;
候选typerows判决
A · idx_score (score)range81,920范围列单打独斗:term 的等值过滤沾不上光,扫完还要回表。聊胜于无。
B · idx_term_score (term, score)range213✓ 等值在前、范围在后:term 钉死起点,score 只走一小段,连 ORDER BY 都顺路解决。
C · idx_title (courses.title)ALL1,204,880建在别人家地里:查询里根本没有 title。

验证记录:1.84 s → 0.03 s,对比卡上墙。出题点就两个:最左前缀、等值列在前,范围列在后——选错一次,比讲三遍记得牢。

03 / CASE-2病例二 · 索引失灵

索引明明在,key 却是 NULL

idx_created_at 建得好好的,查询却全表扫描。让学生自己找出「手术痕迹」。

case2.sql · 对索引列做手术 key = NULL
-- 病历: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 倍
写法typerows耗时
YEAR(created_at) = 2026ALL2,318,4421.92 s
created_at 范围写法range316,2040.31 s

同病名单(点名让学生对号):对索引列套函数或运算(score + 50 < 90)、隐式类型转换(字符串列拿数字查)、LIKE '%xx' 前导通配符、OR 两侧没有全索引。一句总结:对索引列做手术,索引就罢工。

04 / CASE-3病例三 · 排序之痛

filtering 很快,排序要命

WHERE 明明走了索引,还是慢——Extra 里的 Using filesort 暴露了真凶。

case3.sql · 最新动态 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,附前后耗时答案去拿 →