📄 一句话概括
慢查询=不报错但要命的语句:结果对、速度慢,用户等得跳脚——治理三步:找出来(慢查询日志)→ 看懂它(执行计划)→ 治好它(索引/改写)。
📝 本节和前面几节的关系
6-5 提过「慢查询是性能侦探」,7-5 刚讲完「报错的病」,本节讲不报错的病:语法全对、结果全对,就是慢。它的特效药是下一节的索引(7-7)——本节负责把病认清楚,下节开药。
一、为什么会慢
- 全表扫描:
WHERE条件没有索引可用,数据库只好一行行翻——10 行无感,1000 万行等死 - JOIN 无索引:两张大表连接时逐行配对(3-20 的连接,没有索引就是灾难)
- SELECT * 抱回整行:传输与解析都浪费
- 函数包住列:
WHERE YEAR(date) = 2026让索引失效——列上套函数=索引白建
二、治理三步
- 找出来:开慢查询日志,设阈值(如超 1 秒的记下来)——6-5 仪表的具体用法
- 看懂它:
EXPLAIN(执行计划)告诉你是全表扫描还是走索引——先诊断再开药 - 治好它:加索引(7-7)、改写语句、缩小结果集
三、动手 Demo:见证 100 万行里的一次「全表扫描」
-- 在线运行器造 10 万行(可改小为 1 万)
CREATE TABLE big (id INTEGER PRIMARY KEY, name TEXT, score INTEGER);
-- 省略批量插入(运行器里用递归 CTE 或多次插入)
-- 慢:name 没索引,全表扫描
SELECT * FROM big WHERE name = 'user_9527';
-- 快:id 有主键索引(PRIMARY KEY 自带),瞬回
SELECT * FROM big WHERE id = 9527;
-- 结论:同一张表、同一个量级,索引有无 = 天壤之别
【准备块】在线 SQLite 运行器;数据量视运行器性能调小,结论不变。
四、30 秒实验
把数据库想成图书馆(1-8 的老朋友):全表扫描=为了找一本书把所有书架翻一遍;索引=书脊上的索书号——先查目录卡再直奔书架。你愿意当哪种读者?
五、常见误区
- 「慢查询是数据库的事,与我无关」:SQL 是人写的——九成慢查询是写语句的人造成的
- 「索引越多越好」:索引本身占空间、拖慢写入(每次 INSERT 都要同步更新所有索引)——7-7 详谈
- 「先优化再测量」:没有慢查询日志和执行计划就瞎优化=蒙眼开药;先测量,后优化
自测三问
1. 慢查询治理三步?(慢查询日志找出来 → EXPLAIN 看懂 → 索引/改写治好) 2. 为什么 `WHERE YEAR(date)=2026` 会拖慢查询?(函数包住列使索引失效,退回全表扫描) 3. 为什么说索引不是免费的?(占空间且每次写入都要同步维护,拖慢 INSERT/UPDATE)- ☐ 下一节(7-7 索引-缩短获取数据的时间)
相关笔记
- 操作历史、日志、资源-监控数据库 —— 「找出来」靠的慢查询日志就在这
- JOIN-合并多个表获取数据 —— 无索引的 JOIN 是慢查询重灾区
- 索引-缩短获取数据的时间 —— 下一节:慢查询的特效药正式登场
- 🗄️ 数据库基础 · 索引 —— 全课路线图