SQL Server 执行计划看不懂?一文教你快速读懂关键信息
SQL Server 执行计划看不懂?一文教你快速读懂关键信息
很多 SQL Server 开发者或 DBA 都有过这种体验:
SQL 跑得慢,打开“执行计划”,满屏的图标、箭头、百分比,一脸懵——到底该看哪里?
这篇文章不堆砌概念,只讲执行计划里真正值得关注的关键信息,帮你从“看不懂”到“能定位问题”。
一、先搞清楚:执行计划是什么?
简单说,执行计划就是 SQL Server 决定“怎么执行你的 SQL”的作战方案:
- 先查哪张表?
- 用索引还是全表扫?
- 怎么关联多张表?
- 中间结果有多大?
SQL Server 会估算每一步的成本、行数、IO、CPU,并以图形 / 文本 / XML 的形式展示出来。
记住一句话:执行计划看的是“预估”和“实际”的差距,以及“代价高”的步骤。
二、如何打开执行计划?
最常用的是图形化执行计划:
- 预估执行计划:SSMS → 工具栏 → “显示预估执行计划”
(不真正执行 SQL,适合评审 SQL) - 实际执行计划:SSMS → 工具栏 → “包括实际的执行计划”
(执行 SQL 后显示,能看到真实行数、实际成本)
快捷键:
- 预估:
Ctrl + L - 实际:
Ctrl + M
三、执行计划必看的 6 个关键信息
1. 箭头粗细:数据流动规模
图形计划里,箭头越粗,代表流经的数据行数越多。
- 某一步箭头特别粗,但逻辑上不应该有这么多数据:
- 可能是 缺少筛选条件
- 或 索引失效导致大量数据参与运算
- 箭头粗细 + 工具提示里的 Estimated / Actual Number of Rows,是判断数据膨胀的重要依据。
✅ 快速判断:一眼扫过去,哪个箭头最粗,问题大概率就在它附近。
2. 百分比成本:谁最“烧资源”
每个图标下方会显示一个百分比,比如:
Table Scan (75%)
这表示 SQL Server 估算这一步占整体成本的 75%。
- 重点看 成本占比最高 的几个操作(通常前 3 个就够)
- 成本占比低的操作(<1%),一般可以先忽略
✅ 经验法则:先优化“大头”,再抠“小头”。
3. 三大“危险操作”(重点)
下面这几个图标,是性能杀手,看到要格外警惕。
(1)Table Scan(表扫描)
- 含义:一行一行扫全表
- 常见于:
- 没有索引
- 索引失效(如对索引列使用函数、隐式转换)
- 优化方向:
- 建立合适的索引
- 避免对索引列做函数包装或类型转换
(2)Clustered Index Scan(聚集索引扫描)
- 含义:扫整个聚集索引(本质也是全表扫描)
- 比 Table Scan 好一点,但依然是“扫全表”
- 如果查询只用到少数几行,却出现这个,多半是 WHERE 条件没命中索引
(3)RID Lookup / Key Lookup(书签查找)
- 含义:先通过非聚集索引找到“指针”,再回表取其他列
- 问题:
- 多次回表,随机 IO 多
- 优化方向:
- 使用 覆盖索引(INCLUDE 列),让非聚集索引“一次拿全数据”
✅ 口诀:Scan 要警惕,Lookup 要减少。
4. 连接类型:Nested Loops / Hash Match / Merge Join
多表 JOIN 时,SQL Server 会选择一种连接算法。
|
连接类型 |
特点 |
适用场景 |
|---|---|---|
|
Nested Loops |
外表一行,内表查一次 |
小表驱动大表,内表有索引 |
|
Hash Join |
先建哈希表,再匹配 |
大表 JOIN 大表,无合适索引 |
|
Merge Join |
两边先排序,再合并 |
两边都有序(如聚集索引),大数据量 |
关注点:
- Nested Loops + 内表多次扫描:可能是内表没索引
- Hash Join 内存溢出(Warning):会写 TempDB,性能差
- Merge Join 但出现 Sort:说明要先排序,成本高
✅ 如果执行计划中频繁出现 Hash Join + Sort,优先考虑索引优化。
5. 排序(Sort):内存杀手
Sort 操作在图标中通常很显眼。
- 排序非常耗内存和 CPU
- 如果 Sort 出现在大表上,成本会很高
- 常见原因:
ORDER BY的列没有索引- 子查询 / 视图中隐含排序
✅ 优化思路:
- 为
ORDER BY/GROUP BY/DISTINCT的列建立合适索引 - 能不排序就不排序
6. 实际行数 vs 预估行数(关键!)
实际执行计划中,工具提示里的两个数字非常重要:
- Estimated Number of Rows(预估行数)
- Actual Number of Rows(实际行数)
如果两者差距巨大(比如预估 10 行,实际 10 万行):
- 统计信息可能过期:
UPDATE STATISTICS 表名 - 参数嗅探问题:执行计划缓存了不合适的参数
- 数据分布极度不均:需要考虑改写 SQL 或调整索引
✅ 这是很多“有时快有时慢”的 SQL 的根源。
四、一个简单阅读流程(实战版)
遇到慢 SQL,可以按这个顺序看图:
- 扫一眼整体:哪个箭头最粗?哪个操作成本最高?
- 找红色/黄色警告:缺失索引、类型转换、哈希溢出等
- 盯三大危险操作:Table Scan / Index Scan / Key Lookup
- 看连接算法:Nested Loops 是否合理?Hash Join 是否必要?
- 核对行数偏差:预估 vs 实际,差距大不大?
- 检查 Sort:是否有不必要的排序?
五、几个常见误区
误区 1:执行计划里成本高的就一定要改
不一定。
如果那一步是 不可避免的业务逻辑(比如必须全表统计),优化空间有限,重点应放在 减少输入/输出数据量 上。
误区 2:有索引就一定会用
SQL Server 会基于成本决定是否用索引。
如果索引选择性差(比如性别字段),或者查询返回大部分数据,全表扫描反而更便宜。
误区 3:只看图形计划就够了
复杂 SQL 建议配合:
SET STATISTICS IO ONSET STATISTICS TIME ON
看物理读、逻辑读、CPU 时间,交叉验证。
六、快速上手的一句话总结
看执行计划,先盯“粗箭头、高成本、全表扫、回表查、大排序、行数差”这六点,80% 的性能问题都能定位。
更多推荐
所有评论(0)