对存储过程右键“执行”看不到执行计划,因为SSMS仅捕获查询编辑器中可见T-SQL的计划;需手动输入EXEC语句并启用“包括实际执行计划”才能获取图形化计划。

EXEC 一个存储过程时,它内部的 SQL 语句会生成执行计划,但直接对存储过程对象本身调用“显示实际执行计划”按钮是无效的——SSMS 不会为你展开并展示其内部语句的计划。你得让 SQL Server 真正执行它,并捕获运行时产生的计划。
为什么对存储过程右键 → “执行”看不到执行计划
SSMS 的右键菜单中“执行存储过程”或“执行存储过程(自定义值)”只是生成一个 EXEC 语句并运行,它默认不启用执行计划捕获。即使你提前点了“包括实际的执行计划”按钮,如果执行语句不是显式写在查询编辑器里(而是由 SSMS 自动生成并隐藏),计划也不会出现在“执行计划”选项卡中。
- 根本原因是:SSMS 只对当前查询编辑器中**可见、可编辑的 T-SQL 文本**启用执行计划捕获
- 加密的存储过程(
WITH ENCRYPTION)完全无法查看任何执行计划,连估计计划都不行 - 如果存储过程中有动态 SQL(
EXEC(@sql)或sp_executesql),那部分语句的计划是独立生成的,不会自动合并到主计划图里
正确做法:把 EXEC 语句手动写进查询编辑器
这是最可靠、开发和 DBA 日常都在用的方式。你不是在“调用存储过程”,而是在“执行一条含 EXEC 的批处理”,这样 SSMS 才能完整捕获整个执行流的计划。
- 在查询编辑器中手动输入:
EXEC YourStoredProcedureName @param1 = 'value1', @param2 = 123; - 确保已点击工具栏上的 “包括实际的执行计划” 按钮(快捷键
Ctrl+M) - 按
F5执行——执行完成后,切换到结果窗格的 “执行计划” 选项卡 - 注意:如果存储过程包含多个语句(如多个 SELECT),执行计划会显示多个子图,每个对应一个语句;顶部会标出各自占批处理总开销的百分比
示例:
SET STATISTICS XML ON; EXEC Sales.GetOrderSummary @CustomerID = 1001; SET STATISTICS XML OFF;
这段代码也能得到 XML 格式计划(输出在“消息”选项卡),但不如图形化界面直观;且 SET STATISTICS XML 在某些权限受限环境可能被禁用。
排查缓存计划:从 sys.dm_exec_query_plan 查看已缓存的执行计划
当存储过程已运行过,它的执行计划大概率已缓存。你可以绕过重跑,直接查内存里的计划快照——这对生产环境排查尤其关键(避免重复执行影响业务)。
- 先定位目标存储过程的
plan_handle:
SELECT
cp.plan_handle,
cp.usecounts,
cp.size_in_bytes,
t.text
FROM sys.dm_exec_cached_plans cp
CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) t
WHERE t.text LIKE '%YourStoredProcedureName%';- 再用
sys.dm_exec_query_plan提取图形化 XML 计划:
SELECT
query_plan
FROM sys.dm_exec_query_plan(<code>0x06000100...</code>); -- 替换为上一步查到的 plan_handle返回的是 XML,可复制粘贴到 SSMS 新建查询窗口,右键 → “在 XML 编辑器中打开”,SSMS 会自动渲染成图形计划(需 SQL Server 2016+)。
⚠️ 注意:sys.dm_exec_cached_plans 中的计划可能被清除(如内存压力、DBCC FREEPROCCACHE、统计信息更新等),所以它反映的是“曾经有过的计划”,未必是最新逻辑下的最优计划。
复杂点在于嵌套与动态 SQL
存储过程里调用另一个存储过程,或拼接字符串后用 sp_executesql 执行,这些语句的执行计划是单独编译、单独缓存的。你在主过程的图形计划里看不到它们的细节,只看到一个 EXECUTE 运算符或 Remote Query 节点。
- 要分析被调用过程,得单独对它做
EXEC+ 实际执行计划 - 对动态 SQL,建议改用
sp_executesql并带参数(而非字符串拼接),这样计划才能被复用;否则每次拼出不同字符串,都会生成新计划,加剧缓存污染 - 如果必须分析某次特定动态 SQL 的计划,可在其前后加
SET STATISTICS XML ON/OFF,并在消息中捕获 XML,再手动解析
真正容易被忽略的,是“你以为看到了完整计划,其实只看到第一层”。执行计划不是树状展开的全家福,而是按语句粒度缓存的快照集合——每条独立执行的语句,都可能有自己的计划分支。

















