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,可以按这个顺序看图:

  1. 扫一眼整体:哪个箭头最粗?哪个操作成本最高?
  2. 找红色/黄色警告:缺失索引、类型转换、哈希溢出等
  3. 盯三大危险操作:Table Scan / Index Scan / Key Lookup
  4. 看连接算法:Nested Loops 是否合理?Hash Join 是否必要?
  5. 核对行数偏差:预估 vs 实际,差距大不大?
  6. 检查 Sort:是否有不必要的排序?

五、几个常见误区

误区 1:执行计划里成本高的就一定要改

不一定。

如果那一步是 不可避免的业务逻辑(比如必须全表统计),优化空间有限,重点应放在 减少输入/输出数据量​ 上。

误区 2:有索引就一定会用

SQL Server 会基于成本决定是否用索引。

如果索引选择性差(比如性别字段),或者查询返回大部分数据,全表扫描反而更便宜。

误区 3:只看图形计划就够了

复杂 SQL 建议配合:

  • SET STATISTICS IO ON
  • SET STATISTICS TIME ON

看物理读、逻辑读、CPU 时间,交叉验证。


六、快速上手的一句话总结

看执行计划,先盯“粗箭头、高成本、全表扫、回表查、大排序、行数差”这六点,80% 的性能问题都能定位。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐