In Microsoft SQL Server come posso ottenere un piano di esecuzione delle query per una query / procedura memorizzata?
In Microsoft SQL Server come posso ottenere un piano di esecuzione delle query per una query / procedura memorizzata?
Risposte:
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.
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 .
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.
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.
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
A meno che tu non abbia una forte preferenza, la mia raccomandazione è di usare l' STATISTICS XML
opzione. 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 querySHOWPLAN_ALL
- Visualizza un piano di esecuzione stimato basato su testo con stime dei costi, senza eseguire la querySHOWPLAN_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.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!
Il piano che ottieni equivale all'opzione "Includi piano di esecuzione effettivo" in SQL Server Management Studio.
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.
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.
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).
Questo è un argomento abbastanza degno per un libro (gratuito) a sé stante.
SET STATISTICS XML ON
all'inizio della query e SET STATISTICS XML OFF|ON
le 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).
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
StartCapture
Definizione di esempioCREATE 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
StopCapture
Definizione di esempioCREATE 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
Supponendo che tu stia utilizzando Microsoft SQL Server Management Studio
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
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.
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.
Maggiori informazioni sulla visualizzazione dei piani di esecuzione sono disponibili seguendo questo link .
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:
È 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.
Speaking of third-party tools
quando nessuno ha menzionato strumenti di terze parti.
I piani di query possono essere ottenuti da una sessione Eventi estesi tramite l' query_post_execution_showplan
evento. 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:
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.
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
Abilitazione dell'archivio query : l' archivio query funziona a livello di database sul server.
tempdb
database.
sys.database_query_store_options
(Transact-SQL)
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+
Come con SQL Server Management Studio (già spiegato), è anche possibile con Datagrip come spiegato qui .
- Fare clic con il tasto destro del mouse su un'istruzione SQL e selezionare Spiega piano.
- Nel riquadro Output, fare clic su Plan.
- 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
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 NULL
o 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
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()
Come ho spiegato in questo articolo , ci sono due tipi di piani di esecuzione che è possibile ottenere quando si utilizza SQL Server.
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_ALL
impostazione 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_ALL
as, altrimenti la sessione del database corrente genererà solo il piano di esecuzione stimato invece di eseguire le query SQL fornite.
SET SHOWPLAN_ALL OFF
Nell'applicazione SQL Server Management Studio, è possibile ottenere facilmente il piano di esecuzione stimato per qualsiasi query SQL premendo il CTRL+L
tasto di scelta rapida.
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, PROFILE
impostazioni, 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 ON
impostazioni in questo modo:
SET STATISTICS IO, TIME, PROFILE OFF
Nell'applicazione SQL Server Management Studio, è possibile ottenere facilmente il piano di esecuzione stimato per qualsiasi query SQL premendo il CTRL+M
tasto di scelta rapida.
Per ulteriori dettagli su come ottenere un piano di esecuzione quando si utilizza SQL Server, consultare questo articolo .
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