你有没有遇到过这样的情况:写好一条 SQL,跑起来卡得像在等泡面煮熟?明明数据量不大,查个用户列表却要 3 秒多。这时候别急着怀疑服务器配置,先看看数据库给你的“路线图”——查询执行计划(Execution Plan)。
执行计划是啥?就是数据库的“导航语音”
你用高德地图查路线,它不会直接说“你走”,而是告诉你:先直行 200 米,右转进小路,再左转过红绿灯……数据库也一样。当你输入一条 SELECT 语句,它不会马上翻表找数据,而是先“想一想”怎么最快拿到结果——是全表扫描?走索引?要不要临时排序?要不要建临时表?这个“思考过程”的详细步骤,就是执行计划。
怎么查?不同数据库命令不一样,但都很简单
MySQL 里加个 EXPLAIN 就行:
EXPLAIN SELECT * FROM orders WHERE user_id = 123 AND status = 'paid';PostgreSQL 用 EXPLAIN ANALYZE,能连真实耗时一起显示:
EXPLAIN ANALYZE SELECT name FROM users WHERE created_at > '2024-01-01';SQL Server 在 SSMS 里点一下「包含实际执行计划」按钮,图形化界面立马弹出来,箭头粗细都代表数据量大小,特别直观。
重点盯哪几项?别被满屏英文吓住
初看执行计划,一堆 type、rows、key、Extra,容易懵。其实盯牢这三样就够了:
- type(访问类型):从
const(常量匹配,最快)到ALL(全表扫描,最慢),中间还有ref(走索引)、range(范围查询);看到ALL就该警觉了。 - rows(预估扫描行数):不是返回行数,而是“数据库打算翻多少行”。如果表有 10 万条,这里显示 98765,基本等于没走索引。
- Extra(额外信息):出现
Using filesort或Using temporary就意味着排序或分组没走索引,可能要优化。
举个真实例子:同事写了个报表 SQL,查近 7 天订单总金额,执行计划里 rows=500000,type=ALL,Extra 还带 Using temporary。一看表结构,created_at 字段根本没索引。加上索引后,rows 直降到 3200,查询从 8 秒变 0.12 秒。
小技巧:执行计划不是万能,但不看它肯定踩坑
注意两点:一是执行计划基于统计信息生成,如果表数据大变(比如刚批量导入 100 万条),记得手动更新统计信息(MySQL 用 ANALYZE TABLE);二是 EXPLAIN 只看“预估”,真耗时还得靠 EXPLAIN ANALYZE 或实际跑一遍测时间。另外,别迷信“走了索引就一定快”——如果索引列选择性差(比如性别字段只有男/女两个值),数据库可能宁愿全表扫描。
下次 SQL 又慢了,别光刷新页面,打开命令行,敲一行 EXPLAIN,花 30 秒看看那张“导航图”,问题常常就浮出水面了。