Come posso ottenere un piano di esecuzione delle query in SQL Server?


338

In Microsoft SQL Server come posso ottenere un piano di esecuzione delle query per una query / procedura memorizzata?


2
Come posso chiudere la scheda Piano di esecuzione in SQL Server Management Studio?
Paul McCarthy,

2
@Paul Puoi premere Ctrl + R per quello. Chiude l'intera sezione dei risultati, inclusi i messaggi e il piano di esecuzione.
Nisarg,

Risposte:


502

Esistono diversi metodi per ottenere un piano di esecuzione, che uno dipenderà dalle circostanze. In genere è possibile utilizzare SQL Server Management Studio per ottenere un piano, tuttavia se per qualche motivo non è possibile eseguire la query in SQL Server Management Studio, potrebbe essere utile ottenere un piano tramite SQL Server Profiler o ispezionando la cache del piano.

Metodo 1: utilizzo di SQL Server Management Studio

SQL Server viene fornito con un paio di funzionalità pulite che rendono molto semplice l'acquisizione di un piano di esecuzione, è sufficiente assicurarsi che la voce di menu "Includi piano di esecuzione effettivo" (che si trova nel menu "Query") sia selezionata ed esegua la query normalmente .

Includi la voce di menu Piano di esecuzione dell'azione

Se si sta tentando di ottenere il piano di esecuzione per le istruzioni in una procedura memorizzata, è necessario eseguire la procedura memorizzata, in questo modo:

exec p_Example 42

Al termine della query, nel riquadro dei risultati verrà visualizzata una scheda aggiuntiva denominata "Piano di esecuzione". Se hai eseguito molte dichiarazioni, potresti visualizzare molti piani visualizzati in questa scheda.

Schermata di un piano di esecuzione

Da qui è possibile controllare il piano di esecuzione in SQL Server Management Studio oppure fare clic con il tasto destro del mouse sul piano e selezionare "Salva piano di esecuzione come ..." per salvare il piano in un file in formato XML.

Metodo 2: utilizzo delle opzioni SHOWPLAN

Questo metodo è molto simile al metodo 1 (in realtà è quello che fa SQL Server Management Studio internamente), tuttavia l'ho incluso per completezza o se non hai SQL Server Management Studio disponibile.

Prima di eseguire la query, eseguire una delle seguenti istruzioni. L'istruzione deve essere l'unica istruzione nel batch, ovvero non è possibile eseguire un'altra istruzione contemporaneamente:

SET SHOWPLAN_TEXT ON
SET SHOWPLAN_ALL ON
SET SHOWPLAN_XML ON
SET STATISTICS PROFILE ON
SET STATISTICS XML ON -- The is the recommended option to use

Queste sono opzioni di connessione e quindi è necessario eseguirlo solo una volta per connessione. Da questo punto in poi tutte le istruzioni eseguite saranno accompagnate da un set di risultati aggiuntivo contenente il piano di esecuzione nel formato desiderato: esegui semplicemente la query come faresti normalmente per vedere il piano.

Una volta terminato, puoi disattivare questa opzione con la seguente dichiarazione:

SET <<option>> OFF

Confronto tra i formati del piano di esecuzione

A meno che tu non abbia una forte preferenza, la mia raccomandazione è di usare l' STATISTICS XMLopzione. Questa opzione è equivalente all'opzione "Includi piano di esecuzione effettivo" in SQL Server Management Studio e fornisce la maggior parte delle informazioni nel formato più conveniente.

  • SHOWPLAN_TEXT - Visualizza un piano di esecuzione stimato basato su testo di base, senza eseguire la query
  • SHOWPLAN_ALL - Visualizza un piano di esecuzione stimato basato su testo con stime dei costi, senza eseguire la query
  • SHOWPLAN_XML- Visualizza un piano di esecuzione stimato basato su XML con stime dei costi, senza eseguire la query. Ciò equivale all'opzione "Visualizza piano di esecuzione stimato ..." in SQL Server Management Studio.
  • STATISTICS PROFILE - Esegue la query e visualizza un piano di esecuzione effettivo basato su testo.
  • STATISTICS XML- Esegue la query e visualizza un piano di esecuzione effettivo basato su XML. Ciò equivale all'opzione "Includi piano di esecuzione effettivo" in SQL Server Management Studio.

Metodo 3: utilizzo di SQL Server Profiler

Se non è possibile eseguire direttamente la query (o la query non viene eseguita lentamente quando la si esegue direttamente - ricordare che vogliamo che un piano della query funzioni male), è possibile acquisire un piano utilizzando una traccia di SQL Server Profiler. L'idea è di eseguire la query mentre è in esecuzione una traccia che sta acquisendo uno degli eventi "Showplan".

Si noti che a seconda del carico è possibile utilizzare questo metodo in un ambiente di produzione, tuttavia è necessario prestare attenzione. I meccanismi di profilazione di SQL Server sono progettati per ridurre al minimo l'impatto sul database, ma ciò non significa che non vi sarà alcun impatto sulle prestazioni. Potresti anche avere problemi a filtrare e identificare il piano corretto nella tua traccia se il tuo database è in forte uso. Dovresti ovviamente verificare con il tuo DBA per vedere se sono contenti che tu lo faccia nel loro prezioso database!

  1. Aprire SQL Server Profiler e creare una nuova traccia collegandosi al database desiderato rispetto al quale si desidera registrare la traccia.
  2. Nella scheda "Selezione eventi" selezionare "Mostra tutti gli eventi", selezionare la riga "Prestazioni" -> "Showplan XML" ed eseguire la traccia.
  3. Mentre la traccia è in esecuzione, fare tutto ciò che è necessario per eseguire la query con esecuzione lenta.
  4. Attendere il completamento della query e interrompere la traccia.
  5. Per salvare la traccia, fare clic con il tasto destro del mouse sull'xml del piano in SQL Server Profiler e selezionare "Estrai dati evento ..." per salvare il piano in un file in formato XML.

Il piano che ottieni equivale all'opzione "Includi piano di esecuzione effettivo" in SQL Server Management Studio.

Metodo 4 - Ispezione della cache delle query

Se non è possibile eseguire direttamente la query e non è anche possibile acquisire una traccia del profiler, è comunque possibile ottenere un piano stimato ispezionando la cache del piano di query SQL.

Ispezioniamo la cache del piano eseguendo una query sui DMV di SQL Server . Di seguito è una query di base che elencherà tutti i piani di query memorizzati nella cache (come xml) insieme al loro testo SQL. Nella maggior parte dei database sarà inoltre necessario aggiungere ulteriori clausole di filtro per filtrare i risultati fino ai soli piani a cui si è interessati.

SELECT UseCounts, Cacheobjtype, Objtype, TEXT, query_plan
FROM sys.dm_exec_cached_plans 
CROSS APPLY sys.dm_exec_sql_text(plan_handle)
CROSS APPLY sys.dm_exec_query_plan(plan_handle)

Eseguire questa query e fare clic sul piano XML per aprire il piano in una nuova finestra. Fare clic con il tasto destro e selezionare "Salva piano di esecuzione come ..." per salvare il piano in un file in formato XML.

Appunti:

Poiché ci sono molti fattori coinvolti (che vanno dalla tabella e dallo schema dell'indice fino ai dati archiviati e alle statistiche della tabella), dovresti sempre cercare di ottenere un piano di esecuzione dal database che ti interessa (normalmente quello che sta vivendo una prestazione problema).

Non è possibile acquisire un piano di esecuzione per stored procedure crittografate.

piani di esecuzione "reali" vs "stimati"

Un piano di esecuzione effettivo è quello in cui SQL Server esegue effettivamente la query, mentre un piano di esecuzione stimato SQL Server stabilisce cosa farebbe senza eseguire la query. Sebbene logicamente equivalente, un piano di esecuzione effettivo è molto più utile in quanto contiene ulteriori dettagli e statistiche su ciò che è effettivamente accaduto durante l'esecuzione della query. Ciò è essenziale quando si diagnosticano problemi in cui le stime dei server SQL sono disattivate (ad esempio quando le statistiche non sono aggiornate).

Come interpretare un piano di esecuzione della query?

Questo è un argomento abbastanza degno per un libro (gratuito) a sé stante.

Guarda anche:


8
Una nota per i futuri lettori: metti SET STATISTICS XML ONall'inizio della query e SET STATISTICS XML OFF|ONle aree circostanti che non vuoi vengano mostrate nell'output del piano: l'ho trovato utile quando la query contiene un'iterazione (WHILE) che non vuoi / ti serve per vedere nel piano di esecuzione (altrimenti sarebbe troppo pesante e lungo per SQL SERVER visualizzarlo).
Roimer,

2
@MonsterMMORPG è possibile utilizzare il metodo 4 e quindi SELEZIONARE. Ad esempio, utilizzando <a href=" github.com/StackExchange/dapper-dot-net"> Dapper.net </… > connection.Query <string> ("SELECT query_plan FROM sys.dm_exec_cached_plans CROSS APPLY sys.dm_exec_sql_text (plan_handle ) CROSS APPLY sys.dm_exec_query_plan (plan_handle) DOVE TESTO COME N '% La tua query originale va qui%' "); Le% sono se si utilizza solo un sottoinsieme della query.
segna il

2
@Justin la 2a edizione del libro a cui ti sei collegato, per l'interpretazione di un piano di esecuzione delle query, è datata dal 2009. Diresti ancora che è una buona risorsa a tale scopo nel 2016?
Abdul,

3
@Abdul Lo stesso autore, Grant Fritchey, ha un libro più recente chiamato Ottimizzazione delle prestazioni delle query di SQL Server che copre le versioni più recenti di SQL Server.
entro il

42

Oltre alla risposta completa già pubblicata a volte, è utile poter accedere al piano di esecuzione in modo programmatico per estrarre informazioni. Di seguito è riportato un esempio di codice.

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

StartCaptureDefinizione di esempio

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

StopCaptureDefinizione di esempio

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

18

Supponendo che tu stia utilizzando Microsoft SQL Server Management Studio

  • Per il piano di query stimato è possibile premere Ctrl + L o il pulsante seguente.

inserisci qui la descrizione dell'immagine

  • Per il piano di query effettivo , è possibile premere Ctrl + M o il pulsante seguente prima di eseguire la query.

inserisci qui la descrizione dell'immagine

  • Per Live Query Plan , (solo in SSMS 2016) utilizzare il pulsante seguente prima di eseguire la query.

inserisci qui la descrizione dell'immagine


15

Oltre ai metodi descritti nelle risposte precedenti, è anche possibile utilizzare un visualizzatore del piano di esecuzione gratuito e lo strumento di ottimizzazione delle query ApexSQL Plan (che ho incontrato di recente).

È possibile installare e integrare il piano ApexSQL in SQL Server Management Studio, in modo che i piani di esecuzione possano essere visualizzati direttamente da SSMS.

Visualizzazione dei piani di esecuzione stimati nel piano ApexSQL

  1. Fare clic sul pulsante Nuova query in SSMS e incollare il testo della query nella finestra del testo della query. Fare clic destro e selezionare l'opzione "Visualizza piano di esecuzione stimato" dal menu di scelta rapida.

Nuovo pulsante Query in SSMS

  1. I diagrammi del piano di esecuzione verranno mostrati nella scheda Piano di esecuzione nella sezione dei risultati. Quindi fare clic con il tasto destro del mouse sul piano di esecuzione e nel menu di scelta rapida selezionare l'opzione "Apri nel piano ApexSQL".

Progetto esecutivo

  1. Il piano di esecuzione stimato verrà aperto nel piano ApexSQL e può essere analizzato per l'ottimizzazione delle query.

Piano di esecuzione stimato

Visualizzazione dei piani di esecuzione effettivi nel piano ApexSQL

Per visualizzare il piano di esecuzione effettivo di una query, continuare dal secondo passaggio menzionato in precedenza, ma ora, una volta visualizzato il piano stimato, fare clic sul pulsante "Attuale" dalla barra multifunzione principale nel piano ApexSQL.

fai clic sul pulsante "Attuale" dalla barra multifunzione principale

Dopo aver fatto clic sul pulsante "Effettivo", verrà mostrato il piano di esecuzione effettivo con un'anteprima dettagliata dei parametri di costo insieme ad altri dati del piano di esecuzione.

Piano di esecuzione effettivo

Maggiori informazioni sulla visualizzazione dei piani di esecuzione sono disponibili seguendo questo link .


14

Il mio strumento preferito per ottenere e analizzare in profondità i piani di esecuzione delle query è SQL Sentry Plan Explorer . È molto più intuitivo, conveniente e completo per l'analisi dei dettagli e la visualizzazione dei piani di esecuzione rispetto a SSMS.

Ecco una schermata di esempio per avere un'idea di quale funzionalità viene offerta dallo strumento:

Schermata della finestra di SQL Sentry Plan Explorer

È solo una delle viste disponibili nello strumento. Notare una serie di schede nella parte inferiore della finestra dell'app, che consente di ottenere diversi tipi di rappresentazione del piano di esecuzione e utili informazioni aggiuntive.

Inoltre, non ho notato alcun limite della sua edizione gratuita che impedisce di usarlo quotidianamente o ti costringe ad acquistare la versione Pro alla fine. Quindi, se preferisci restare con l'edizione gratuita, nulla ti impedisce di farlo.

AGGIORNAMENTO: (Grazie a Martin Smith ) Plan Explorer ora è gratuito! Vedi http://www.sqlsentry.com/products/plan-explorer/sql-server-query-view per i dettagli.


1
Chi stava parlando di strumenti di terze parti?
basher

12
@basher: OP non ha limitato i mezzi con gli strumenti MS o in qualche altro modo. Quindi cosa ti fa pensare che una risposta che coinvolge uno strumento di terze parti sia inappropriata?
Alexander Abakumov,

3
Stavo solo scherzando su come hai definito l'inizio della tua risposta Speaking of third-party toolsquando nessuno ha menzionato strumenti di terze parti.
basher

4
@basher: Oh, bella cattura! Grazie! Ho riscritto la mia risposta. Sentiti libero di dare un feedback e / o votarlo se vuoi.
Alexander Abakumov,


7

I piani di query possono essere ottenuti da una sessione Eventi estesi tramite l' query_post_execution_showplanevento. Ecco una sessione di esempio XEvent:

/*
    Generated via "Query Detail Tracking" template.
*/
CREATE EVENT SESSION [GetExecutionPlan] ON SERVER 
ADD EVENT sqlserver.query_post_execution_showplan(
    ACTION(package0.event_sequence,sqlserver.plan_handle,sqlserver.query_hash,sqlserver.query_plan_hash,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_frame,sqlserver.tsql_stack)),

/* Remove any of the following events (or include additional events) as desired. */
ADD EVENT sqlserver.error_reported(
    ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.database_id,sqlserver.plan_handle,sqlserver.query_hash,sqlserver.query_plan_hash,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_frame,sqlserver.tsql_stack)
    WHERE ([package0].[greater_than_uint64]([sqlserver].[database_id],(4)) AND [package0].[equal_boolean]([sqlserver].[is_system],(0)))),
ADD EVENT sqlserver.module_end(SET collect_statement=(1)
    ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.database_id,sqlserver.plan_handle,sqlserver.query_hash,sqlserver.query_plan_hash,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_frame,sqlserver.tsql_stack)
    WHERE ([package0].[greater_than_uint64]([sqlserver].[database_id],(4)) AND [package0].[equal_boolean]([sqlserver].[is_system],(0)))),
ADD EVENT sqlserver.rpc_completed(
    ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.database_id,sqlserver.plan_handle,sqlserver.query_hash,sqlserver.query_plan_hash,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_frame,sqlserver.tsql_stack)
    WHERE ([package0].[greater_than_uint64]([sqlserver].[database_id],(4)) AND [package0].[equal_boolean]([sqlserver].[is_system],(0)))),
ADD EVENT sqlserver.sp_statement_completed(SET collect_object_name=(1)
    ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.database_id,sqlserver.plan_handle,sqlserver.query_hash,sqlserver.query_plan_hash,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_frame,sqlserver.tsql_stack)
    WHERE ([package0].[greater_than_uint64]([sqlserver].[database_id],(4)) AND [package0].[equal_boolean]([sqlserver].[is_system],(0)))),
ADD EVENT sqlserver.sql_batch_completed(
    ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.database_id,sqlserver.plan_handle,sqlserver.query_hash,sqlserver.query_plan_hash,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_frame,sqlserver.tsql_stack)
    WHERE ([package0].[greater_than_uint64]([sqlserver].[database_id],(4)) AND [package0].[equal_boolean]([sqlserver].[is_system],(0)))),
ADD EVENT sqlserver.sql_statement_completed(
    ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.database_id,sqlserver.plan_handle,sqlserver.query_hash,sqlserver.query_plan_hash,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_frame,sqlserver.tsql_stack)
    WHERE ([package0].[greater_than_uint64]([sqlserver].[database_id],(4)) AND [package0].[equal_boolean]([sqlserver].[is_system],(0)))) 
ADD TARGET package0.ring_buffer
WITH (MAX_MEMORY=4096 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=30 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=NONE,TRACK_CAUSALITY=ON,STARTUP_STATE=OFF)
GO

Dopo aver creato la sessione, (in SSMS) passare a Esplora oggetti e approfondire Gestione | Eventi estesi | Sessions. Fare clic con il tasto destro del mouse sulla sessione "GetExecutionPlan" e avviarlo. Fai di nuovo clic con il tasto destro del mouse e seleziona "Guarda dati live".

Quindi, aprire una nuova finestra di query ed eseguire una o più query. Eccone uno per AdventureWorks:

USE AdventureWorks;
GO

SELECT p.Name AS ProductName, 
    NonDiscountSales = (OrderQty * UnitPrice),
    Discounts = ((OrderQty * UnitPrice) * UnitPriceDiscount)
FROM Production.Product AS p 
INNER JOIN Sales.SalesOrderDetail AS sod
    ON p.ProductID = sod.ProductID 
ORDER BY ProductName DESC;
GO

Dopo un momento o due, dovresti vedere alcuni risultati nella scheda "GetExecutionPlan: Live Data". Fare clic su uno degli eventi query_post_execution_showplan nella griglia, quindi fare clic sulla scheda "Piano di query" sotto la griglia. Dovrebbe apparire simile a questo:

inserisci qui la descrizione dell'immagine

MODIFICARE : il codice XEvent e la schermata sono stati generati da SQL / SSMS 2012 con SP2. Se stai usando SQL 2008 / R2, potresti essere in grado di modificare lo script per farlo funzionare. Ma quella versione non ha una GUI, quindi dovresti estrarre lo showplan XML, salvarlo come file * .sqlplan e aprirlo in SSMS. È ingombrante. XEvents non esisteva in SQL 2005 o versioni precedenti. Quindi, se non sei su SQL 2012 o versioni successive, ti consiglio vivamente una delle altre risposte pubblicate qui.


5

A partire da SQL Server 2016+, è stata introdotta la funzionalità Query Store per monitorare le prestazioni. Fornisce informazioni dettagliate sulla scelta e sulle prestazioni del piano di query. Non è una sostituzione completa di traccia o eventi estesi, ma poiché si sta evolvendo da una versione all'altra, potremmo ottenere un archivio di query completamente funzionale nelle versioni future di SQL Server. Il flusso principale di Query Store

  1. I componenti esistenti di SQL Server interagiscono con l'archivio query utilizzando Gestione archivio query.
  2. Il Gestore negozio query determina quale negozio deve essere utilizzato e quindi passa l'esecuzione a quel negozio (statistiche piano o runtime o statistiche attesa query)
    • Store Plan: persistenza delle informazioni sul piano di esecuzione
    • Archivio statistiche di runtime: persistenza delle informazioni sulle statistiche di esecuzione
    • Archivio statistiche attesa query: informazioni statistiche sull'attesa persistente.
  3. Plan, Runtime Stats e Wait store utilizzano Query Store come estensione di SQL Server.

inserisci qui la descrizione dell'immagine

  1. Abilitazione dell'archivio query : l' archivio query funziona a livello di database sul server.

    • Query Store non è attivo per i nuovi database per impostazione predefinita.
    • Non è possibile abilitare l'archivio query per il master o il tempdbdatabase.
    • DMV disponibile

      sys.database_query_store_options (Transact-SQL)

  2. Raccogliere informazioni nel Query Store : raccogliamo tutte le informazioni disponibili dai tre negozi utilizzando Query Store DMV (Data Management Views).

    • Archivio del piano di query: persistenza delle informazioni del piano di esecuzione ed è responsabile della cattura di tutte le informazioni relative alla compilazione delle query.

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

    • Archivio statistiche di runtime: persistenza delle informazioni sulle statistiche di esecuzione ed è probabilmente l'archivio aggiornato più frequentemente. Queste statistiche rappresentano i dati di esecuzione della query.

      sys.query_store_runtime_stats (Transact-SQL)

    • Archivio statistiche attesa query: persistenza e acquisizione delle informazioni statistiche sull'attesa.

      sys.query_store_wait_stats (Transact-SQL)

NOTA: l' archivio statistiche di attesa query è disponibile solo in SQL Server 2017+


4

Come con SQL Server Management Studio (già spiegato), è anche possibile con Datagrip come spiegato qui .

  1. Fare clic con il tasto destro del mouse su un'istruzione SQL e selezionare Spiega piano.
  2. Nel riquadro Output, fare clic su Plan.
  3. Per impostazione predefinita, viene visualizzata la rappresentazione ad albero della query. Per visualizzare il piano di query, fai clic sull'icona Mostra visualizzazione o premi Ctrl + Maiusc + Alt + U

3

Ecco una cosa importante da sapere oltre a tutto ciò che è stato detto prima.

I piani di query sono spesso troppo complessi per essere rappresentati dal tipo di colonna XML incorporato che ha una limitazione di 127 livelli di elementi nidificati. Questo è uno dei motivi per cui sys.dm_exec_query_plan potrebbe restituire NULLo addirittura generare un errore nelle precedenti versioni di MS SQL, quindi in genere è più sicuro utilizzare sys.dm_exec_text_query_plan . Quest'ultimo ha anche un'utile caratteristica bonus di selezionare un piano per una specifica dichiarazione piuttosto che l'intero lotto. Ecco come lo usi per visualizzare i piani per le dichiarazioni attualmente in esecuzione:

SELECT p.query_plan
FROM sys.dm_exec_requests AS r
OUTER APPLY sys.dm_exec_text_query_plan(
                r.plan_handle,
                r.statement_start_offset,
                r.statement_end_offset) AS p

La colonna di testo nella tabella risultante non è tuttavia molto utile rispetto a una colonna XML. Per poter fare clic sul risultato da aprire in una scheda separata come diagramma, senza dover salvare il suo contenuto in un file, puoi usare un piccolo trucco (ricorda che non puoi semplicemente usare CAST(... AS XML)), anche se funzionerà solo per un fila unica:

SELECT Tag = 1, Parent = NULL, [ShowPlanXML!1!!XMLTEXT] = query_plan
FROM sys.dm_exec_text_query_plan(
                -- set these variables or copy values
                -- from the results of the above query
                @plan_handle,
                @statement_start_offset,
                @statement_end_offset)
FOR XML EXPLICIT

3

Puoi anche farlo tramite PowerShell usando SET STATISTICS XML ON per ottenere il piano reale. L'ho scritto in modo tale da fondere piani multiistruzione in un piano;

    ########## 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()

2

Come ho spiegato in questo articolo , ci sono due tipi di piani di esecuzione che è possibile ottenere quando si utilizza SQL Server.

Piano di esecuzione stimato

Il piano di esecuzione stimato viene generato dall'ottimizzatore senza eseguire la query SQL.

Per ottenere il piano di esecuzione stimato, è necessario abilitare l' SHOWPLAN_ALLimpostazione prima di eseguire la query.

SET SHOWPLAN_ALL ON

Ora, quando si esegue la seguente query SQL:

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 genererà il seguente piano di esecuzione stimato:

| 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                 |

Dopo aver eseguito la query, siamo interessati a ottenere il piano di esecuzione stimato, è necessario disabilitare SHOWPLAN_ALLas, altrimenti la sessione del database corrente genererà solo il piano di esecuzione stimato invece di eseguire le query SQL fornite.

SET SHOWPLAN_ALL OFF

Piano stimato di SQL Server Management Studio

Nell'applicazione SQL Server Management Studio, è possibile ottenere facilmente il piano di esecuzione stimato per qualsiasi query SQL premendo il CTRL+Ltasto di scelta rapida.

inserisci qui la descrizione dell'immagine

Piano di esecuzione effettivo

Il piano di esecuzione SQL effettivo viene generato dall'ottimizzatore durante l'esecuzione della query SQL. Se le statistiche della tabella del database sono accurate, il piano effettivo non dovrebbe differire in modo significativo da quello stimato.

Per ottenere il piano di esecuzione effettivo su SQL Server, è necessario abilitare le STATISTICS IO, TIME, PROFILEimpostazioni, come illustrato dal seguente comando SQL:

SET STATISTICS IO, TIME, PROFILE ON

Ora, quando si esegue la query precedente, SQL Server genererà il seguente piano di esecuzione:

| 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.

Dopo aver eseguito la query, siamo interessati a ottenere il piano di esecuzione effettivo, è necessario disabilitare le STATISTICS IO, TIME, PROFILE ONimpostazioni in questo modo:

SET STATISTICS IO, TIME, PROFILE OFF

Piano effettivo di SQL Server Management Studio

Nell'applicazione SQL Server Management Studio, è possibile ottenere facilmente il piano di esecuzione stimato per qualsiasi query SQL premendo il CTRL+Mtasto di scelta rapida.

inserisci qui la descrizione dell'immagine

Per ulteriori dettagli su come ottenere un piano di esecuzione quando si utilizza SQL Server, consultare questo articolo .


0

La spiegazione del piano di esecuzione può essere molto dettagliata e richiede parecchio tempo di lettura, ma in sintesi se si utilizza "spiega" prima della query, si dovrebbero fornire molte informazioni, incluse le parti eseguite per prime e così via. se vuoi leggere un po 'più di dettagli su questo, ho compilato un piccolo blog su questo che indica anche i riferimenti giusti. https://medium.com/swlh/jetbrains-datagrip-explain-plan-ac406772c470

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.