No Microsoft SQL Server, como posso obter um plano de execução de uma consulta / procedimento armazenado?
No Microsoft SQL Server, como posso obter um plano de execução de uma consulta / procedimento armazenado?
Respostas:
Existem vários métodos para obter um plano de execução, o qual usar dependerá de suas circunstâncias. Geralmente, você pode usar o SQL Server Management Studio para obter um plano; no entanto, se por algum motivo não puder executar sua consulta no SQL Server Management Studio, poderá ser útil obter um plano via SQL Server Profiler ou inspecionando o cache do plano.
O SQL Server vem com alguns recursos interessantes que facilitam a captura de um plano de execução, basta verificar se o item de menu "Incluir Plano de Execução Real" (encontrado no menu "Consulta") está marcado e executar sua consulta normalmente. .
Se você estiver tentando obter o plano de execução para instruções em um procedimento armazenado, execute o procedimento armazenado, da seguinte maneira:
exec p_Example 42
Quando sua consulta for concluída, você verá uma guia extra intitulada "Plano de execução" no painel de resultados. Se você executou muitas instruções, poderá ver muitos planos exibidos nesta guia.
Aqui, você pode inspecionar o plano de execução no SQL Server Management Studio ou clicar com o botão direito do mouse no plano e selecionar "Salvar plano de execução como ..." para salvar o plano em um arquivo no formato XML.
Esse método é muito semelhante ao método 1 (de fato, é o que o SQL Server Management Studio faz internamente); no entanto, eu o incluí por completo ou se você não possui o SQL Server Management Studio disponível.
Antes de executar sua consulta, execute uma das seguintes instruções. A instrução deve ser a única instrução do lote, ou seja, você não pode executar outra instrução ao mesmo tempo:
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
Essas são opções de conexão e, portanto, você só precisa executá-la uma vez por conexão. A partir desse ponto, todas as instruções executadas serão acompanhadas por um conjunto de resultados adicional contendo seu plano de execução no formato desejado - basta executar sua consulta como faria normalmente para ver o plano.
Quando terminar, você pode desativar esta opção com a seguinte instrução:
SET <<option>> OFF
A menos que você tenha uma forte preferência, minha recomendação é usar a STATISTICS XML
opção Essa opção é equivalente à opção "Incluir plano de execução real" no SQL Server Management Studio e fornece mais informações no formato mais conveniente.
SHOWPLAN_TEXT
- Exibe um plano de execução estimado baseado em texto básico, sem executar a consultaSHOWPLAN_ALL
- Exibe um plano de execução estimado baseado em texto com estimativas de custo, sem executar a consultaSHOWPLAN_XML
- Exibe um plano de execução estimado baseado em XML com estimativas de custo, sem executar a consulta. Isso é equivalente à opção "Exibir plano de execução estimado ..." no SQL Server Management Studio.STATISTICS PROFILE
- Executa a consulta e exibe um plano de execução real baseado em texto.STATISTICS XML
- Executa a consulta e exibe um plano de execução real baseado em XML. Isso é equivalente à opção "Incluir plano de execução real" no SQL Server Management Studio.Se você não puder executar sua consulta diretamente (ou sua consulta não for lenta lentamente quando executada diretamente - lembre-se de que queremos que um plano da consulta tenha um desempenho ruim), você poderá capturar um plano usando um rastreamento do SQL Server Profiler. A idéia é executar sua consulta enquanto um rastreamento que está capturando um dos eventos "Showplan" está em execução.
Observe que, dependendo da carga, você pode usar esse método em um ambiente de produção, no entanto, obviamente, você deve ter cuidado. Os mecanismos de perfis SQL Server são projetados para minimizar o impacto sobre o banco de dados, mas isso não significa que não haverá qualquer impacto no desempenho. Você também pode ter problemas para filtrar e identificar o plano correto em seu rastreio, se o banco de dados estiver sob uso intenso. Obviamente, você deve verificar com seu DBA para ver se eles estão felizes com você fazendo isso em seu precioso banco de dados!
O plano que você obtém é equivalente à opção "Incluir plano de execução real" no SQL Server Management Studio.
Se você não puder executar sua consulta diretamente e também não conseguir capturar um rastreamento do criador de perfil, ainda poderá obter um plano estimado inspecionando o cache do plano de consulta SQL.
Inspecionamos o cache do plano consultando as DMVs do SQL Server . A seguir, é apresentada uma consulta básica que lista todos os planos de consulta em cache (como xml) junto com o texto SQL. Na maioria dos bancos de dados, você também precisará adicionar cláusulas de filtragem adicionais para filtrar os resultados apenas nos planos nos quais está interessado.
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)
Execute esta consulta e clique no XML do plano para abrir o plano em uma nova janela - clique com o botão direito do mouse e selecione "Salvar plano de execução como ..." para salvar o plano em arquivo no formato XML.
Como existem muitos fatores envolvidos (desde o esquema da tabela e do índice até os dados armazenados e as estatísticas da tabela), você deve sempre tentar obter um plano de execução do banco de dados em que está interessado (normalmente aquele que está apresentando desempenho) problema).
Você não pode capturar um plano de execução para procedimentos armazenados criptografados.
Um plano de execução real é aquele em que o SQL Server realmente executa a consulta, enquanto um plano de execução estimado do SQL Server executa o que ele faria sem executar a consulta. Embora logicamente equivalente, um plano de execução real é muito mais útil, pois contém detalhes e estatísticas adicionais sobre o que realmente aconteceu ao executar a consulta. Isso é essencial ao diagnosticar problemas em que as estimativas dos Servidores SQL estão desativadas (como quando as estatísticas estão desatualizadas).
Esse é um tópico digno o suficiente para um livro (gratuito) por si só.
SET STATISTICS XML ON
o início da consulta e SET STATISTICS XML OFF|ON
as áreas adjacentes que você não deseja que apareçam na saída do plano: achei isso útil quando a consulta contém uma iteração (ENQUANTO) você não deseja / precisa para ver no plano de execução (caso contrário, seria muito pesado e demorado para o SQL SERVER exibi-lo).
Além da resposta abrangente já publicada às vezes, é útil poder acessar o plano de execução programaticamente para extrair informações. Código de exemplo para isso está abaixo.
DECLARE @TraceID INT
EXEC StartCapture @@SPID, @TraceID OUTPUT
EXEC sp_help 'sys.objects' /*<-- Call your stored proc of interest here.*/
EXEC StopCapture @TraceID
StartCapture
Definição de ExemploCREATE 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
Definição de ExemploCREATE 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
Supondo que você esteja usando o Microsoft SQL Server Management Studio
Além dos métodos descritos nas respostas anteriores, você também pode usar um visualizador de plano de execução gratuito e a ferramenta de otimização de consultas ApexSQL Plan (na qual recentemente me deparei).
Você pode instalar e integrar o ApexSQL Plan ao SQL Server Management Studio, para que os planos de execução possam ser visualizados diretamente do SSMS.
Exibindo planos de execução estimados no plano ApexSQL
Exibindo planos de execução reais no plano ApexSQL
Para visualizar o plano de execução real de uma consulta, continue a partir da 2ª etapa mencionada anteriormente, mas agora, depois que o plano Estimado for exibido, clique no botão "Real" na barra de faixa de opções principal do ApexSQL Plan.
Depois que o botão "Real" é clicado, o plano de execução real será mostrado com uma visualização detalhada dos parâmetros de custo, juntamente com outros dados do plano de execução.
Mais informações sobre a visualização de planos de execução podem ser encontradas seguindo este link .
Minha ferramenta favorita para obter e analisar profundamente os planos de execução de consultas é o SQL Sentry Plan Explorer . É muito mais fácil de usar, conveniente e abrangente para a análise e visualização detalhadas dos planos de execução do que o SSMS.
Aqui está um exemplo de captura de tela para você ter uma idéia de qual funcionalidade é oferecida pela ferramenta:
É apenas uma das visualizações disponíveis na ferramenta. Observe um conjunto de guias na parte inferior da janela do aplicativo, que permite obter diferentes tipos de representação do seu plano de execução e também informações adicionais úteis.
Além disso, não notei nenhuma limitação de sua edição gratuita que impeça o uso diário ou o force a comprar a versão Pro eventualmente. Portanto, se você prefere ficar com a edição gratuita, nada o impede de fazê-lo.
ATUALIZAÇÃO: (Obrigado a Martin Smith ) O Plan Explorer agora é gratuito! Consulte http://www.sqlsentry.com/products/plan-explorer/sql-server-query-view para obter detalhes.
Speaking of third-party tools
quando ninguém mencionou ferramentas de terceiros.
Os planos de consulta podem ser obtidos em uma sessão de Eventos Estendidos por meio do query_post_execution_showplan
evento. Aqui está uma amostra da sessão 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
Depois de criar a sessão, (no SSMS), vá para o Pesquisador de Objetos e mergulhe em Gerenciamento | Eventos estendidos | Sessões. Clique com o botão direito do mouse na sessão "GetExecutionPlan" e inicie-a. Clique com o botão direito do mouse novamente e selecione "Watch Live Data".
Em seguida, abra uma nova janela de consulta e execute uma ou mais consultas. Aqui está um para o 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
Após alguns instantes, você verá alguns resultados na guia "GetExecutionPlan: Live Data". Clique em um dos eventos query_post_execution_showplan na grade e clique na guia "Plano de consulta" abaixo da grade. Deve ser semelhante a este:
EDIT : O código XEvent e a captura de tela foram gerados a partir do SQL / SSMS 2012 com SP2. Se você estiver usando SQL 2008 / R2, você pode ser capaz de ajustar o script para fazê-lo funcionar. Mas essa versão não possui uma GUI, portanto você precisaria extrair o XML do showplan, salvá-lo como um arquivo * .sqlplan e abri-lo no SSMS. Isso é complicado. XEvents não existia no SQL 2005 ou anterior. Portanto, se você não estiver no SQL 2012 ou posterior, sugiro fortemente uma das outras respostas postadas aqui.
A partir do SQL Server 2016+, o recurso Query Store foi introduzido para monitorar o desempenho. Ele fornece informações sobre a escolha e o desempenho do plano de consulta. Não é uma substituição completa de eventos de rastreamento ou estendidos, mas, à medida que evolui de versão para versão, podemos obter um armazenamento de consultas totalmente funcional em versões futuras do SQL Server. O fluxo primário do Query Store
Habilitando o Query Store : O Query Store funciona no nível do banco de dados no servidor.
tempdb
banco de dados.
sys.database_query_store_options
(Transact-SQL)
Coletar informações no Query Store : Coletamos todas as informações disponíveis das três lojas usando o Query Store DMV (Data Management Views).
Armazenamento do plano de consulta: Persiste nas informações do plano de execução e é responsável por capturar todas as informações relacionadas à compilação de consultas.
sys.query_store_query
(Transact-SQL)sys.query_store_plan
(Transact-SQL)sys.query_store_query_text
(Transact-SQL)
Armazenamento de Estatísticas de Tempo de Execução: Persiste nas informações de estatísticas de execução e é provavelmente o armazenamento atualizado com mais freqüência. Essas estatísticas representam dados de execução da consulta.
sys.query_store_runtime_stats
(Transact-SQL)
Armazenamento de estatísticas de espera de consulta: persistindo e capturando informações de estatísticas de espera.
sys.query_store_wait_stats
(Transact-SQL)
NOTA: O Armazenamento de Estatísticas de Espera de Consulta está disponível apenas no SQL Server 2017+
Como no SQL Server Management Studio (já explicado), também é possível com o Datagrip, conforme explicado aqui .
- Clique com o botão direito do mouse em uma instrução SQL e selecione Explain plan.
- No painel Saída, clique em Planejar.
- Por padrão, você vê a representação em árvore da consulta. Para ver o plano de consulta, clique no ícone Mostrar Visualização ou pressione Ctrl + Shift + Alt + U
Aqui está uma coisa importante a saber, além de tudo o que foi dito antes.
Os planos de consulta geralmente são muito complexos para serem representados pelo tipo de coluna XML interno que possui uma limitação de 127 níveis de elementos aninhados. Esse é um dos motivos pelos quais o sys.dm_exec_query_plan pode retornar NULL
ou até gerar um erro nas versões anteriores do MS SQL, portanto, geralmente é mais seguro usar o sys.dm_exec_text_query_plan . O último também possui um recurso de bônus útil para selecionar um plano para uma declaração específica, em vez de para todo o lote. Veja como você o usa para exibir planos para instruções em execução no momento:
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
A coluna de texto na tabela resultante, no entanto, não é muito útil em comparação com uma coluna XML. Para poder clicar no resultado a ser aberto em uma guia separada como um diagrama, sem precisar salvar seu conteúdo em um arquivo, você pode usar um pequeno truque (lembre-se de que não pode apenas usar CAST(... AS XML)
), embora isso funcione apenas para um 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
Como expliquei neste artigo , existem dois tipos de plano de execução que você pode obter ao usar o SQL Server.
O plano de execução estimado é gerado pelo Optimizer sem executar a consulta SQL.
Para obter o plano de execução estimado, você precisa habilitar a SHOWPLAN_ALL
configuração antes de executar a consulta.
DEFINIR SHOWPLAN_ALL ON
Agora, ao executar a seguinte consulta 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
O SQL Server irá gerar o seguinte plano estimado de execução:
| 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 |
Depois de executar a consulta, estamos interessados em obter o plano de execução estimado, é necessário desativar o SHOWPLAN_ALL
, pois, caso contrário, a sessão atual do banco de dados gerará apenas o plano de execução estimado em vez de executar as consultas SQL fornecidas.
SET SHOWPLAN_ALL OFF
No aplicativo SQL Server Management Studio, você pode obter facilmente o plano de execução estimado para qualquer consulta SQL pressionando o CTRL+L
atalho de tecla.
O plano de execução real do SQL é gerado pelo Optimizer ao executar a consulta SQL. Se as estatísticas da tabela do banco de dados forem precisas, o plano real não deve diferir significativamente do estimado.
Para obter o plano de execução real no SQL Server, é necessário habilitar as STATISTICS IO, TIME, PROFILE
configurações, conforme ilustrado pelo seguinte comando SQL:
SET STATISTICS IO, TIME, PROFILE ON
Agora, ao executar a consulta anterior, o SQL Server gerará o seguinte plano de execução:
| 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.
Depois de executar a consulta, estamos interessados em obter o plano de execução real, é necessário desativar as STATISTICS IO, TIME, PROFILE ON
configurações como esta:
SET STATISTICS IO, TIME, PROFILE OFF
No aplicativo SQL Server Management Studio, você pode obter facilmente o plano de execução estimado para qualquer consulta SQL pressionando o CTRL+M
atalho de tecla.
Para obter mais detalhes sobre como obter um plano de execução ao usar o SQL Server, confira este artigo .
Você também pode fazê-lo via PowerShell usando SET STATISTICS XML ON para obter o plano real. Escrevi para mesclar planos de múltiplas instruções em um único plano;
########## 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()
Explicar o plano de execução pode ser muito detalhado e leva bastante tempo para ler, mas, em resumo, se você usar 'explanar' antes da consulta, ele deverá fornecer muitas informações, incluindo quais partes foram executadas primeiro e assim por diante. se você quiser ler um pouco mais de detalhes sobre isso, compilei um pequeno blog sobre isso, que também indica as referências corretas. https://medium.com/swlh/jetbrains-datagrip-explain-plan-ac406772c470