【问题标题】: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

【问题讨论】:

    标签: sql-server stored-procedures optimization ssms


    【解决方案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】:

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

          【讨论】:

          • 阅读问题和几个热门答案也值一千字
          猜你喜欢
          • 1970-01-01
          • 2015-09-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-10-16
          • 1970-01-01
          • 2010-10-05
          • 2022-10-05
          相关资源
          最近更新 更多