如何显示存储过程的执行计划?

Posted

技术标签:

【中文标题】如何显示存储过程的执行计划?【英文标题】:How can I display the execution plan for a stored procedure? 【发布时间】:2010-10-22 02:51:44 【问题描述】:

我可以毫无问题地查看查询的估计执行计划 (Management Studio 9.0),但是对于存储过程,如果不从 ALTER 屏幕复制代码并粘贴,我看不到一种简单的方法来执行此操作它进入一个查询窗口,否则它将显示 ALTER 的计划而不是过程。即使在这样做之后,任何输入都丢失了,我需要这样声明它们。

有没有更简单的方法在存储过程上执行此操作?

编辑: 我只是想到了一些可行的方法,但我不确定。

我能做一下估计的执行计划吗

exec myStoredProc 234

【问题讨论】:

【参考方案1】:
SET SHOWPLAN_ALL ON
GO

-- FMTONLY will not exec stored proc
SET FMTONLY ON
GO

exec yourproc
GO

SET FMTONLY OFF
GO

SET SHOWPLAN_ALL OFF
GO

【讨论】:

为什么没有记录在任何地方? 'FMT_ONLY' 不是公认的 SET 选项。 我认为是 FMTONLY 而不是 FMT_ONLY 虽然不是可视化预估的执行计划,但还是可以的! 顺便说一句,如果您想要图形计划,请将 SHOWPLAN_ALL 替换为 SHOWPLAN_XML。然后,您可以单击 SSMS 中带下划线的 XML。【参考方案2】:

选择存储过程名称(只需在查询窗口中键入),右键单击,然后选择 SQl Server Mgmt Studio 工具栏中的“显示估计执行计划”按钮。 注意,您不必打开存储过程代码。只需选择过程名称。

调用过程中存储过程的计划也将以图形形式显示。

【讨论】:

【参考方案3】:

在 SQL Management Studio 2008 中执行存储过程时,您可以从菜单中单击查询 -> 包括实际执行计划...它也在工具栏上

阅读完 cmets 执行似乎是一个问题,为了解决这个问题,我建议将存储过程的执行包装在最后回滚的事务中

【讨论】:

我实际上无法运行它。需要估算。 你可以把它包装在一个事务中而不是提交【参考方案4】:

使用

SET SHOWPLAN_ALL ON
Go
exec myStoredProc 234
GO
SET SHOWPLAN_ALL OFF
GO

见http://msdn.microsoft.com/en-us/library/aa259203.aspx 只要您不使用 tmp 表,我认为这将起作用

【讨论】:

【参考方案5】:

我知道答案是不久前提交的,但我发现下面的查询很有用

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

SELECT  [ProcedureName]          =   OBJECT_NAME([ps].[object_id], [ps].[database_id]) 
       ,[ProcedureExecutes]      =   [ps].[execution_count] 
       ,[VersionOfPlan]          =   [qs].[plan_generation_num]
       ,[ExecutionsOfCurrentPlan]    =   [qs].[execution_count] 
       ,[Query Plan XML]         =   [qp].[query_plan]  

FROM       [sys].[dm_exec_procedure_stats] AS [ps]
       JOIN [sys].[dm_exec_query_stats] AS [qs] ON [ps].[plan_handle] = [qs].[plan_handle]
       CROSS APPLY [sys].[dm_exec_query_plan]([qs].[plan_handle]) AS [qp]
WHERE   [ps].[database_id] = DB_ID() 
       AND  OBJECT_NAME([ps].[object_id], [ps].[database_id])  = 'TEST'

【讨论】:

我假设这提供了历史信息?在新的存储过程中可能没有用 试一试,它给出了sproc版本、执行次数和查询计划。 我用它来解决计划未被重用的sprocs【参考方案6】:

有很多方法可以获取存储过程的实际执行计划。

SELECT
qp.query_plan, 
SQLText.text
FROM sys.dm_exec_cached_plans AS CP
 CROSS APPLY sys.dm_exec_sql_text( plan_handle)AS SQLText
 CROSS APPLY sys.dm_exec_query_plan( plan_handle)AS QP
 WHERE objtype = 'Proc' and cp.cacheobjtype = 'Compiled Plan'

使用生产服务器中的数据统计信息查看生产服务器上的计划可能会显示与具有较小数据集的开发盒不同的计划。

还有很多数据要查看,例如根据查询缓存执行过程的频率

SELECT
    qp.query_plan, 
    CP.usecounts as [Executed], 
    DB_name(QP.dbid) as [Database],
    OBJECT_NAME(QP.objectid) as [Procedure],
    SQLText.text as [TSQL],
    so.create_date as [Procedure Created],
    so.modify_date as [Procedure  Modified]
FROM sys.dm_exec_cached_plans AS CP
CROSS APPLY sys.dm_exec_sql_text( plan_handle)AS SQLText
CROSS APPLY sys.dm_exec_query_plan( plan_handle)AS QP
join sys.objects as so on so.[object_id]=QP.objectid
WHERE objtype = 'Proc' and cp.cacheobjtype = 'Compiled Plan'

XML 查询计划(两个查询中的第一列),包含执行计划的 XML,允许您在 SSMS 中单击它并查看实际计划,但也允许您扫描您不喜欢的事情有索引扫描或“上帝禁止”表扫描。

SELECT
    qp.query_plan, 
    CP.usecounts as [Executed], 
    DB_name(QP.dbid) as [Database],
    OBJECT_NAME(QP.objectid) as [Procedure],
    SQLText.text as [TSQL],
    so.create_date as [Procedure Created],
    so.modify_date as [Procedure  Modified]
FROM sys.dm_exec_cached_plans AS CP
CROSS APPLY sys.dm_exec_sql_text( plan_handle)AS SQLText
CROSS APPLY sys.dm_exec_query_plan( plan_handle)AS QP
join sys.objects as so on so.[object_id]=QP.objectid
WHERE objtype = 'Proc' and cp.cacheobjtype = 'Compiled Plan'
and cast(qp.query_plan as nvarchar(max)) like '%loop%'

我使用一种非常糟糕的方式进行采样,将 XML 转换为字符串,然后进行通配符搜索,但是 XML 查询并不是每天最常做的事情,字符串通配符对每个人来说都很容易。

【讨论】:

【参考方案7】:

在启用显示实际执行计划(从查询菜单)的情况下在管理工作室(或查询分析器)中运行存储过程将在您运行存储过程后向您显示该存储过程的计划。如果您无法运行它,则会显示估计的执行计划(尽管根据我的经验,这通常不太准确。)

【讨论】:

你错过了我的问题的重点。当我使用“显示估计的执行计划”时,它显示的是 ALTER 的计划,而不是实际的过程。 对不起,我不清楚我的意思是运行我的意思是运行存储过程而不是运行改变。在新窗口中执行 MySP 'param1', 'param2' 并设置估计的执行计划选项 好的,但无论哪种方式我都无法运行该过程,因为它会导致我的数据发生变化。 你没有测试系统?【参考方案8】:

您还可以使用 Profiler 查看执行计划。您需要包括 Performance : Show Plan Statistics Profile 选项,并确保在您的列中包含二进制数据。

然后您可以运行任何查询或过程并查看执行计划。

编辑

如果您不能使用分析器,并且不想打开另一个窗口,我建议您在存储过程的开头包含一个注释块。例如想象一下:

/* 
     Description: This procedure does XYZ etc...
     DevelopedBy: Josh
     Created On:  4/27/09

     Execution: exec my_procName N'sampleparam', N'sampleparam'
*/

ALTER PROCEDURE  my_procName
   @p1 nvarchar(20),
   @p2 nvarchar(20)

AS

这允许您仅突出显示执行目的并打开显示执行计划。并运行它。

【讨论】:

很遗憾我没有 SQL 管理员,所以我无法使用分析器。 我实际上认为,如果您获得正确的权限,您可以以非管理员身份运行分析器。但是不确定这些是什么。【参考方案9】:

这是一个屏幕截图。我花了一段时间才弄清楚在哪里寻找。

【讨论】:

阅读问题和几个热门答案也值一千字

以上是关于如何显示存储过程的执行计划?的主要内容,如果未能解决你的问题,请参考以下文章

怎样让sqlserver后台定时执行某个存储过程

获取存储过程 sqlplus 的执行计划

如何在 IBM Data Studio 中查看 DB2 存储过程的解释计划?

SqlServer 中如何查看某一个Sql语句是复用了执行计划,还是重新生成了执行计划

sqlserver如何自动调用存储过程, 24小时执行一次?

存储过程被程序和第三方客户端执行很慢,而sql server management studio执行速度正常