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

前端 未结 12 1897
不知归路
不知归路 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:07

    Beside the methods described in previous answers, you can also use a free execution plan viewer and query optimization tool ApexSQL Plan (which I’ve recently bumped into).

    You can install and integrate ApexSQL Plan into SQL Server Management Studio, so execution plans can be viewed from SSMS directly.

    Viewing Estimated execution plans in ApexSQL Plan

    1. Click the New Query button in SSMS and paste the query text in the query text window. Right click and select the “Display Estimated Execution Plan” option from the context menu.

    1. The execution plan diagrams will be shown the Execution Plan tab in the results section. Next right-click the execution plan and in the context menu select the “Open in ApexSQL Plan” option.

    1. The Estimated execution plan will be opened in ApexSQL Plan and it can be analyzed for query optimization.

    Viewing Actual execution plans in ApexSQL Plan

    To view the Actual execution plan of a query, continue from the 2nd step mentioned previously, but now, once the Estimated plan is shown, click the “Actual” button from the main ribbon bar in ApexSQL Plan.

    Once the “Actual” button is clicked, the Actual execution plan will be shown with detailed preview of the cost parameters along with other execution plan data.

    More information about viewing execution plans can be found by following this link.

    0 讨论(0)
  • 2020-11-21 05:10

    You can also do it via powershell using SET STATISTICS XML ON to get the actual plan. I've written it so that it merges multi-statement plans into one plan;

        ########## BEGIN : SCRIPT VARIABLES #####################
        [string]$server = '.\MySQLServer'
        [string]$database = 'MyDatabase'
        [string]$sqlCommand = 'EXEC sp_ExampleSproc'
        [string]$XMLOutputFileName = 'sp_ExampleSproc'
        [string]$XMLOutputPath = 'C:\SQLDumps\ActualPlans\'
        ########## END   : SCRIPT VARIABLES #####################
    
        #Set up connection
        $connectionString = "Persist Security Info=False;Integrated Security=true;Connection Timeout=0;Initial Catalog=$database;Server=$server"
        $connection = new-object system.data.SqlClient.SQLConnection($connectionString)
    
        #Set up commands
        $command = new-object system.data.sqlclient.sqlcommand($sqlCommand,$connection)
        $command.CommandTimeout = 0
        $commandXMLActPlanOn = new-object system.data.sqlclient.sqlcommand("SET STATISTICS XML ON",$connection)
        $commandXMLActPlanOff = new-object system.data.sqlclient.sqlcommand("SET STATISTICS XML OFF",$connection)
    
        $connection.Open()
    
        #Enable session XML plan
        $result = $commandXMLActPlanOn.ExecuteNonQuery()
    
        #Execute SP and return resultsets into a dataset
        $adapter = New-Object System.Data.sqlclient.sqlDataAdapter $command
        $dataset = New-Object System.Data.DataSet
        $adapter.Fill($dataSet) | Out-Null
    
        #Set up output file name and path
        [string]$fileNameDateStamp = get-date -f yyyyMMdd_HHmmss
        [string]$XMLOutputFilePath = "$XMLOutputPath$XMLOutputFileName`_$fileNameDateStamp.sqlplan"
    
        #Pull XML plans out of dataset and merge into one multi-statement plan
        [int]$cntr = 1
        ForEach($table in $dataset.Tables)
        {
                if($table.Columns[0].ColumnName -eq "Microsoft SQL Server 2005 XML Showplan")
                {
    
                    [string]$fullXMLPlan = $Table.rows[0]."Microsoft SQL Server 2005 XML Showplan"
    
                    if($cntr -eq 1)
                        {
    
                        [regex]$rx = "\<ShowPlanXML xmlns\=.{1,}\<Statements\>"
                        [string]$startXMLPlan = $rx.Match($fullXMLPlan).Value
                        [regex]$rx = "\<\/Statements\>.{1,}\<\/ShowPlanXML\>"
                        [string]$endXMLPlan = $rx.Match($fullXMLPlan).Value
    
                        $startXMLPlan | out-file -Append -FilePath $XMLOutputFilePath
    
                        }
    
                    [regex]$rx = "\<StmtSimple.{1,}\<\/StmtSimple\>"
                    [string]$bodyXMLPlan = $rx.Match($fullXMLPlan).Value
    
                    $bodyXMLPlan | out-file -Append -FilePath $XMLOutputFilePath
    
                    $cntr += 1
                } 
        }
    
        $endXMLPlan | out-file -Append -FilePath $XMLOutputFilePath
    
        #Disable session XML plan
        $result = $commandXMLActPlanOff.ExecuteNonQuery()
    
        $connection.Close()
    
    0 讨论(0)
  • 2020-11-21 05:13

    Starting from SQL Server 2016+, Query Store feature was introduced to monitor performance. It provides insight into query plan choice and performance. It’s not a complete replacement of trace or extended events, but as it’s evolving from version to version, we might get a fully functional query store in future releases from SQL Server. The primary flow of Query Store

    1. SQL Server existing components interact with query store by utilising Query Store Manager.
    2. Query Store Manager determines which Store should be used and then passes execution to that store (Plan or Runtime Stats or Query Wait Stats)
      • Plan Store - Persisting the execution plan information
      • Runtime Stats Store - Persisting the execution statistics information
      • Query Wait Stats Store - Persisting wait statistics information.
    3. Plan, Runtime Stats and Wait store uses Query Store as an extension to SQL Server.

    1. Enabling the Query Store: Query Store works at the database level on the server.

      • Query Store is not active for new databases by default.
      • You cannot enable the query store for the master or tempdb database.
      • Available DMV

        sys.database_query_store_options (Transact-SQL)

    2. Collect Information in the Query Store: We collect all the available information from the three stores using Query Store DMV (Data Management Views).

      • Query Plan Store: Persisting the execution plan information and it is accountable for capturing all information that is related to query compilation.

        sys.query_store_query (Transact-SQL) sys.query_store_plan (Transact-SQL) sys.query_store_query_text (Transact-SQL)

      • Runtime Stats Store: Persisting the execution statistics information and it is probably the most frequently updated store. These statistics represent query execution data.

        sys.query_store_runtime_stats (Transact-SQL)

      • Query Wait Stats Store: Persisting and capturing wait statistics information.

        sys.query_store_wait_stats (Transact-SQL)

    NOTE: Query Wait Stats Store is available only in SQL Server 2017+

    0 讨论(0)
  • 2020-11-21 05:13

    As I explained in this article, there are two execution plan types you can get when using SQL Server.

    Estimated execution plan

    The estimated execution plan is generated by the Optimizer without running the SQL query.

    In order to get the estimated execution plan, you need to enable the SHOWPLAN_ALL setting prior to executing the query.

    SET SHOWPLAN_ALL ON

    Now, when executing the following SQL query:

    SELECT p.id
    FROM post p
    WHERE EXISTS (
      SELECT 1
      FROM post_comment pc
      WHERE
        pc.post_id = p.id AND
        pc.review = 'Bingo'
    )
    ORDER BY p.title
    OFFSET 20 ROWS
    FETCH NEXT 10 ROWS ONLY
    

    SQL Server will generate the following estimated execution plan:

    | NodeId | Parent | LogicalOp            | EstimateRows | EstimateIO  | EstimateCPU | AvgRowSize | TotalSubtreeCost | EstimateExecutions |
    |--------|--------|----------------------|--------------|-------------|-------------|------------|------------------|--------------------|
    | 1      | 0      | NULL                 | 10           | NULL        | NULL        | NULL       | 0.03374284       | NULL               |
    | 2      | 1      | Top                  | 10           | 0           | 3.00E-06    | 15         | 0.03374284       | 1                  |
    | 4      | 2      | Distinct Sort        | 30           | 0.01126126  | 0.000504114 | 146        | 0.03373984       | 1                  |
    | 5      | 4      | Inner Join           | 46.698       | 0           | 0.00017974  | 146        | 0.02197446       | 1                  |
    | 6      | 5      | Clustered Index Scan | 43           | 0.004606482 | 0.0007543   | 31         | 0.005360782      | 1                  |
    | 7      | 5      | Clustered Index Seek | 1            | 0.003125    | 0.0001581   | 146        | 0.0161733        | 43                 |
    

    After running the query we are interested in getting the estimated execution plan, you need to disable the SHOWPLAN_ALL as, otherwise, the current database session will only generate estimated execution plan instead of executing the provided SQL queries.

    SET SHOWPLAN_ALL OFF
    

    SQL Server Management Studio estimated plan

    In the SQL Server Management Studio application, you can easily get the estimated execution plan for any SQL query by hitting the CTRL+L key shortcut.

    Actual execution plan

    The actual SQL execution plan is generated by the Optimizer when running the SQL query. If the database table statistics are accurate, the actual plan should not differ significantly from the estimated one.

    To get the actual execution plan on SQL Server, you need to enable the STATISTICS IO, TIME, PROFILE settings, as illustrated by the following SQL command:

    SET STATISTICS IO, TIME, PROFILE ON
    

    Now, when running the previous query, SQL Server is going to generate the following execution plan:

    | Rows | Executes | NodeId | Parent | LogicalOp            | EstimateRows | EstimateIO  | EstimateCPU | AvgRowSize | TotalSubtreeCost |
    |------|----------|--------|--------|----------------------|--------------|-------------|-------------|------------|------------------|
    | 10   | 1        | 1      | 0      | NULL                 | 10           | NULL        | NULL        | NULL       | 0.03338978       |
    | 10   | 1        | 2      | 1      | Top                  | 1.00E+01     | 0           | 3.00E-06    | 15         | 0.03338978       |
    | 30   | 1        | 4      | 2      | Distinct Sort        | 30           | 0.01126126  | 0.000478783 | 146        | 0.03338679       |
    | 41   | 1        | 5      | 4      | Inner Join           | 44.362       | 0           | 0.00017138  | 146        | 0.02164674       |
    | 41   | 1        | 6      | 5      | Clustered Index Scan | 41           | 0.004606482 | 0.0007521   | 31         | 0.005358581      |
    | 41   | 41       | 7      | 5      | Clustered Index Seek | 1            | 0.003125    | 0.0001581   | 146        | 0.0158571        |
    
    SQL Server parse and compile time:
       CPU time = 8 ms, elapsed time = 8 ms.
    
    (10 row(s) affected)
    Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
    Table 'post'. Scan count 0, logical reads 116, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
    Table 'post_comment'. Scan count 1, logical reads 5, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
    
    (6 row(s) affected)
    
    SQL Server Execution Times:
       CPU time = 0 ms,  elapsed time = 1 ms.
    

    After running the query we are interested in getting the actual execution plan, you need to disable the STATISTICS IO, TIME, PROFILE ON settings like this:

    SET STATISTICS IO, TIME, PROFILE OFF
    

    SQL Server Management Studio actual plan

    In the SQL Server Management Studio application, you can easily get the estimated execution plan for any SQL query by hitting the CTRL+M key shortcut.

    For more details about getting an execution plan when using SQL Server, check out this article.

    0 讨论(0)
  • 2020-11-21 05:14

    My favourite tool for obtaining and deeply analyzing query execution plans is SQL Sentry Plan Explorer. It's much more user-friendly, convenient and comprehensive for the detail analysis and visualization of execution plans than SSMS.

    Here is a sample screen shot for you to have an idea of what functionality is offered by the tool:

    It's only one of the views available in the tool. Notice a set of tabs to the bottom of the app window, which lets you get different types of your execution plan representation and useful additional information as well.

    In addition, I haven't noticed any limitations of its free edition that prevents using it on a daily basis or forces you to purchase the Pro version eventually. So, if you prefer to stick with the free edition, nothing forbids you from doing so.

    UPDATE: (Thanks to Martin Smith) Plan Explorer now is free! See http://www.sqlsentry.com/products/plan-explorer/sql-server-query-view for details.

    0 讨论(0)
  • 2020-11-21 05:16

    Like with SQL Server Management Studio (already explained), it is also possible with Datagrip as explained here.

    1. Right-click an SQL statement, and select Explain plan.
    2. In the Output pane, click Plan.
    3. By default, you see the tree representation of the query. To see the query plan, click the Show Visualization icon, or press Ctrl+Shift+Alt+U
    0 讨论(0)
提交回复
热议问题