How do I obtain a Query Execution Plan in SQL Server?

前端 未结 12 1933
不知归路
不知归路 2020-11-21 04:17

In Microsoft SQL Server how can I get a query execution plan for a query / stored procedure?

12条回答
  •  栀梦
    栀梦 (楼主)
    2020-11-21 05:05

    In addition to the comprehensive answer already posted sometimes it is useful to be able to access the execution plan programatically to extract information. Example code for this is below.

    DECLARE @TraceID INT
    EXEC StartCapture @@SPID, @TraceID OUTPUT
    EXEC sp_help 'sys.objects' /*<-- Call your stored proc of interest here.*/
    EXEC StopCapture @TraceID
    

    Example StartCapture Definition

    CREATE PROCEDURE StartCapture
    @Spid INT,
    @TraceID INT OUTPUT
    AS
    DECLARE @maxfilesize BIGINT = 5
    DECLARE @filepath NVARCHAR(200) = N'C:\trace_' + LEFT(NEWID(),36)
    
    EXEC sp_trace_create @TraceID OUTPUT, 0, @filepath, @maxfilesize, NULL 
    
    exec sp_trace_setevent @TraceID, 122, 1, 1
    exec sp_trace_setevent @TraceID, 122, 22, 1
    exec sp_trace_setevent @TraceID, 122, 34, 1
    exec sp_trace_setevent @TraceID, 122, 51, 1
    exec sp_trace_setevent @TraceID, 122, 12, 1
    -- filter for spid
    EXEC sp_trace_setfilter @TraceID, 12, 0, 0, @Spid
    -- start the trace
    EXEC sp_trace_setstatus @TraceID, 1
    

    Example StopCapture Definition

    CREATE  PROCEDURE StopCapture
    @TraceID INT
    AS
    WITH  XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' as sql), 
          CTE
         as (SELECT CAST(TextData AS VARCHAR(MAX)) AS TextData,
                    ObjectID,
                    ObjectName,
                    EventSequence,
                    /*costs accumulate up the tree so the MAX should be the root*/
                    MAX(EstimatedTotalSubtreeCost) AS EstimatedTotalSubtreeCost
             FROM   fn_trace_getinfo(@TraceID) fn
                    CROSS APPLY fn_trace_gettable(CAST(value AS NVARCHAR(200)), 1)
                    CROSS APPLY (SELECT CAST(TextData AS XML) AS xPlan) x
                    CROSS APPLY (SELECT T.relop.value('@EstimatedTotalSubtreeCost',
                                                'float') AS EstimatedTotalSubtreeCost
                                 FROM   xPlan.nodes('//sql:RelOp') T(relop)) ca
             WHERE  property = 2
                    AND TextData IS NOT NULL
                    AND ObjectName not in ( 'StopCapture', 'fn_trace_getinfo' )
             GROUP  BY CAST(TextData AS VARCHAR(MAX)),
                       ObjectID,
                       ObjectName,
                       EventSequence)
    SELECT ObjectName,
           SUM(EstimatedTotalSubtreeCost) AS EstimatedTotalSubtreeCost
    FROM   CTE
    GROUP  BY ObjectID,
              ObjectName  
    
    -- Stop the trace
    EXEC sp_trace_setstatus @TraceID, 0
    -- Close and delete the trace
    EXEC sp_trace_setstatus @TraceID, 2
    GO
    

提交回复
热议问题