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

前端 未结 12 1943
不知归路
不知归路 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: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 = "\"
                        [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 = "\"
                    [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()
    

提交回复
热议问题