En Microsoft SQL Server, ¿cómo puedo obtener un plan de ejecución de consultas para una consulta / procedimiento almacenado?
En Microsoft SQL Server, ¿cómo puedo obtener un plan de ejecución de consultas para una consulta / procedimiento almacenado?
Respuestas:
Existen varios métodos para obtener un plan de ejecución, el cual dependerá de sus circunstancias. Por lo general, puede usar SQL Server Management Studio para obtener un plan, sin embargo, si por alguna razón no puede ejecutar su consulta en SQL Server Management Studio, puede resultarle útil obtener un plan a través de SQL Server Profiler o inspeccionando el caché del plan
SQL Server viene con un par de características que hacen que sea muy fácil capturar un plan de ejecución, simplemente asegúrese de que el elemento de menú "Incluir plan de ejecución real" (que se encuentra en el menú "Consulta") esté marcado y ejecute su consulta de forma normal .
Si está tratando de obtener el plan de ejecución para las declaraciones en un procedimiento almacenado, entonces debe ejecutar el procedimiento almacenado de la siguiente manera:
exec p_Example 42
Cuando finalice su consulta, debería ver una pestaña adicional titulada "Plan de ejecución" en el panel de resultados. Si ejecutó muchas declaraciones, es posible que vea muchos planes en esta pestaña.
Desde aquí puede inspeccionar el plan de ejecución en SQL Server Management Studio, o hacer clic con el botón derecho en el plan y seleccionar "Guardar plan de ejecución como ..." para guardar el plan en un archivo en formato XML.
Este método es muy similar al método 1 (de hecho, esto es lo que SQL Server Management Studio hace internamente), sin embargo, lo he incluido para completarlo o si no tiene SQL Server Management Studio disponible.
Antes de ejecutar su consulta, ejecute una de las siguientes declaraciones. La declaración debe ser la única declaración en el lote, es decir, no puede ejecutar otra declaración al mismo tiempo:
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
Estas son opciones de conexión, por lo que solo necesita ejecutar esto una vez por conexión. A partir de este momento, todas las declaraciones ejecutadas estarán acompañadas por un conjunto de resultados adicional que contiene su plan de ejecución en el formato deseado; simplemente ejecute su consulta como lo haría normalmente para ver el plan.
Una vez que haya terminado, puede desactivar esta opción con la siguiente declaración:
SET <<option>> OFF
A menos que tenga una fuerte preferencia, mi recomendación es utilizar la STATISTICS XML
opción. Esta opción es equivalente a la opción "Incluir plan de ejecución real" en SQL Server Management Studio y proporciona la mayor cantidad de información en el formato más conveniente.
SHOWPLAN_TEXT
- Muestra un plan de ejecución estimado basado en texto básico, sin ejecutar la consultaSHOWPLAN_ALL
- Muestra un plan de ejecución estimado basado en texto con estimaciones de costos, sin ejecutar la consultaSHOWPLAN_XML
- Muestra un plan de ejecución estimado basado en XML con estimaciones de costos, sin ejecutar la consulta. Esto es equivalente a la opción "Mostrar plan de ejecución estimado ..." en SQL Server Management Studio.STATISTICS PROFILE
- Ejecuta la consulta y muestra un plan de ejecución real basado en texto.STATISTICS XML
- Ejecuta la consulta y muestra un plan de ejecución real basado en XML. Esto es equivalente a la opción "Incluir plan de ejecución real" en SQL Server Management Studio.Si no puede ejecutar su consulta directamente (o su consulta no se ejecuta lentamente cuando la ejecuta directamente; recuerde que queremos que un plan de la consulta tenga un mal rendimiento), puede capturar un plan utilizando un seguimiento de SQL Server Profiler. La idea es ejecutar su consulta mientras se ejecuta una traza que captura uno de los eventos de "Showplan".
Tenga en cuenta que dependiendo de la carga puede usar este método en un entorno de producción, sin embargo, obviamente, debe tener precaución. Los mecanismos de creación de perfiles de SQL Server están diseñados para minimizar el impacto en la base de datos, pero esto no significa que no habrá ningún impacto en el rendimiento. También puede tener problemas para filtrar e identificar el plan correcto en su rastreo si su base de datos está bajo uso intensivo. ¡Obviamente, debe consultar con su DBA para ver si están contentos con usted haciendo esto en su preciosa base de datos!
El plan que obtiene es equivalente a la opción "Incluir plan de ejecución real" en SQL Server Management Studio.
Si no puede ejecutar su consulta directamente y tampoco puede capturar un seguimiento del generador de perfiles, aún puede obtener un plan estimado inspeccionando la caché del plan de consulta SQL.
Inspeccionamos el caché del plan consultando los DMV de SQL Server . La siguiente es una consulta básica que enumerará todos los planes de consulta en caché (como xml) junto con su texto SQL. En la mayoría de las bases de datos, también deberá agregar cláusulas de filtrado adicionales para filtrar los resultados a los planes que le interesen.
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)
Ejecute esta consulta y haga clic en el plan XML para abrir el plan en una nueva ventana. Haga clic con el botón derecho y seleccione "Guardar plan de ejecución como ..." para guardar el plan en un archivo en formato XML.
Debido a que hay tantos factores involucrados (que van desde la tabla y el esquema de índice hasta los datos almacenados y las estadísticas de la tabla), siempre debe intentar obtener un plan de ejecución de la base de datos que le interesa (normalmente el que está experimentando un rendimiento problema).
No puede capturar un plan de ejecución para procedimientos almacenados cifrados.
Un plan de ejecución real es aquel en el que SQL Server realmente ejecuta la consulta, mientras que un plan de ejecución estimado SQL Server resuelve lo que haría sin ejecutar la consulta. Aunque lógicamente equivalente, un plan de ejecución real es mucho más útil ya que contiene detalles y estadísticas adicionales sobre lo que realmente sucedió al ejecutar la consulta. Esto es esencial cuando se diagnostican problemas en los que las estimaciones de los servidores SQL están desactivadas (como cuando las estadísticas no están actualizadas).
Este es un tema lo suficientemente digno para un libro (gratuito) por derecho propio.
SET STATISTICS XML ON
el principio de la consulta y SET STATISTICS XML OFF|ON
las áreas circundantes que no desea que se muestren en la salida del plan: esto me pareció útil cuando la consulta contiene una iteración (MIENTRAS) que no desea / necesita para ver en el plan de ejecución (de lo contrario, sería demasiado pesado y largo para que SQL SERVER lo muestre).
Además de la respuesta integral ya publicada, a veces es útil poder acceder programáticamente al plan de ejecución para extraer información. El código de ejemplo para esto está abajo.
DECLARE @TraceID INT
EXEC StartCapture @@SPID, @TraceID OUTPUT
EXEC sp_help 'sys.objects' /*<-- Call your stored proc of interest here.*/
EXEC StopCapture @TraceID
StartCapture
Definición de ejemploCREATE 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
Definición de ejemploCREATE 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
Suponiendo que está utilizando Microsoft SQL Server Management Studio
Además de los métodos descritos en las respuestas anteriores, también puede usar un visor de plan de ejecución gratuito y una herramienta de optimización de consultas ApexSQL Plan (que me he encontrado recientemente).
Puede instalar e integrar el Plan ApexSQL en SQL Server Management Studio, para que los planes de ejecución se puedan ver directamente desde SSMS.
Visualización de planes de ejecución estimados en el Plan ApexSQL
Ver planes de ejecución reales en el plan ApexSQL
Para ver el plan de ejecución real de una consulta, continúe desde el segundo paso mencionado anteriormente, pero ahora, una vez que se muestra el plan estimado, haga clic en el botón "Actual" de la barra de cinta principal en el plan ApexSQL.
Una vez que se hace clic en el botón "Actual", se mostrará el plan de ejecución real con una vista previa detallada de los parámetros de costo junto con otros datos del plan de ejecución.
Puede encontrar más información sobre cómo ver los planes de ejecución siguiendo este enlace .
Mi herramienta favorita para obtener y analizar en profundidad los planes de ejecución de consultas es SQL Sentry Plan Explorer . Es mucho más fácil de usar, conveniente y completo para el análisis detallado y la visualización de planes de ejecución que SSMS.
Aquí hay una captura de pantalla de muestra para que tenga una idea de la funcionalidad que ofrece la herramienta:
Es solo una de las vistas disponibles en la herramienta. Observe un conjunto de pestañas en la parte inferior de la ventana de la aplicación, que le permite obtener diferentes tipos de representación de su plan de ejecución e información adicional útil también.
Además, no he notado ninguna limitación de su edición gratuita que evite su uso diario o lo obligue a comprar la versión Pro eventualmente. Por lo tanto, si prefiere seguir con la edición gratuita, nada le impide hacerlo.
ACTUALIZACIÓN: (Gracias a Martin Smith ) ¡Plan Explorer ahora es gratis! Consulte http://www.sqlsentry.com/products/plan-explorer/sql-server-query-view para obtener más detalles.
Speaking of third-party tools
cuando nadie mencionó herramientas de terceros.
Los planes de consulta se pueden obtener de una sesión de eventos extendidos a través del query_post_execution_showplan
evento. Aquí hay una sesión de muestra 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
Después de crear la sesión, (en SSMS) vaya al Explorador de objetos y profundice en Administración | Eventos extendidos | Sesiones Haga clic derecho en la sesión "GetExecutionPlan" e iníciela. Haga clic derecho nuevamente y seleccione "Ver datos en vivo".
A continuación, abra una nueva ventana de consulta y ejecute una o más consultas. Aquí hay uno para 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
Después de un momento o dos, debería ver algunos resultados en la pestaña "GetExecutionPlan: Live Data". Haga clic en uno de los eventos query_post_execution_showplan en la cuadrícula y luego haga clic en la pestaña "Plan de consulta" debajo de la cuadrícula. Debería ser similar a esto:
EDITAR : El código XEvent y la captura de pantalla se generaron a partir de SQL / SSMS 2012 con SP2. Si está utilizando SQL 2008 / R2, es posible que pueda modificar el script para que se ejecute. Pero esa versión no tiene una GUI, por lo que tendría que extraer el XML del plan de presentación, guardarlo como un archivo * .sqlplan y abrirlo en SSMS. Eso es engorroso. XEvents no existía en SQL 2005 o anterior. Entonces, si no está en SQL 2012 o posterior, le sugiero una de las otras respuestas publicadas aquí.
A partir de SQL Server 2016+, se introdujo la función Query Store para monitorear el rendimiento. Proporciona información sobre la elección del plan de consulta y el rendimiento. No es un reemplazo completo de seguimiento o eventos extendidos, pero a medida que evoluciona de una versión a otra, podríamos obtener un almacén de consultas completamente funcional en futuras versiones de SQL Server. El flujo primario de Query Store
Habilitación del Almacén de consultas : El Almacén de consultas funciona en el nivel de la base de datos en el servidor.
tempdb
base de datos.
sys.database_query_store_options
(Transact-SQL)
Recopilar información en el almacén de consultas : Recopilamos toda la información disponible de los tres almacenes utilizando el DMV de consultas (vistas de gestión de datos).
Almacén de planes de consulta: conserva la información del plan de ejecución y es responsable de capturar toda la información relacionada con la compilación de consultas.
sys.query_store_query
(Transact-SQL)sys.query_store_plan
(Transact-SQL)sys.query_store_query_text
(Transact-SQL)
Runtime Stats Store: persiste la información de las estadísticas de ejecución y es probablemente la tienda actualizada con más frecuencia. Estas estadísticas representan datos de ejecución de consultas.
sys.query_store_runtime_stats
(Transact-SQL)
Query Wait Stats Store: persistente y capturando información de estadísticas de espera.
sys.query_store_wait_stats
(Transact-SQL)
NOTA: Query Wait Stats Store solo está disponible en SQL Server 2017+
Al igual que con SQL Server Management Studio (ya explicado), también es posible con Datagrip como se explica aquí .
- Haga clic con el botón derecho en una instrucción SQL y seleccione Explicar plan.
- En el panel Salida, haga clic en Plan.
- De forma predeterminada, verá la representación en árbol de la consulta. Para ver el plan de consulta, haga clic en el icono Mostrar visualización o presione Ctrl + Shift + Alt + U
Aquí hay una cosa importante que debes saber además de todo lo dicho antes.
Los planes de consulta a menudo son demasiado complejos para ser representados por el tipo de columna XML incorporado que tiene una limitación de 127 niveles de elementos anidados. Esa es una de las razones por las que sys.dm_exec_query_plan puede devolver NULL
o incluso arrojar un error en versiones anteriores de MS SQL, por lo que generalmente es más seguro usar sys.dm_exec_text_query_plan . Este último también tiene una característica útil adicional de seleccionar un plan para un estado de cuenta particular en lugar de todo el lote. A continuación, le mostramos cómo lo usa para ver los planes para las declaraciones actualmente en ejecución:
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
Sin embargo, la columna de texto en la tabla resultante no es muy útil en comparación con una columna XML. Para poder hacer clic en el resultado que se abrirá en una pestaña separada como un diagrama, sin tener que guardar su contenido en un archivo, puede usar un pequeño truco (recuerde que no puede usarlo CAST(... AS XML)
), aunque esto solo funcionará para un unica fila:
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 expliqué en este artículo , hay dos tipos de planes de ejecución que puede obtener al usar SQL Server.
El optimizador genera el plan de ejecución estimado sin ejecutar la consulta SQL.
Para obtener el plan de ejecución estimado, debe habilitar la SHOWPLAN_ALL
configuración antes de ejecutar la consulta.
SET SHOWPLAN_ALL ON
Ahora, al ejecutar la siguiente 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
SQL Server generará el siguiente plan de ejecución estimado:
| 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 |
Después de ejecutar la consulta, estamos interesados en obtener el plan de ejecución estimado, debe deshabilitar SHOWPLAN_ALL
ya que, de lo contrario, la sesión de la base de datos actual solo generará el plan de ejecución estimado en lugar de ejecutar las consultas SQL proporcionadas.
SET SHOWPLAN_ALL OFF
En la aplicación SQL Server Management Studio, puede obtener fácilmente el plan de ejecución estimado para cualquier consulta SQL CTRL+L
presionando el atajo de teclado.
El optimizador genera el plan de ejecución SQL real cuando ejecuta la consulta SQL. Si las estadísticas de la tabla de la base de datos son precisas, el plan real no debe diferir significativamente del estimado.
Para obtener el plan de ejecución real en SQL Server, debe habilitar la STATISTICS IO, TIME, PROFILE
configuración, como se ilustra en el siguiente comando SQL:
SET STATISTICS IO, TIME, PROFILE ON
Ahora, al ejecutar la consulta anterior, SQL Server generará el siguiente plan de ejecución:
| 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.
Después de ejecutar la consulta, estamos interesados en obtener el plan de ejecución real, debe deshabilitar la STATISTICS IO, TIME, PROFILE ON
configuración de esta manera:
SET STATISTICS IO, TIME, PROFILE OFF
En la aplicación SQL Server Management Studio, puede obtener fácilmente el plan de ejecución estimado para cualquier consulta SQL CTRL+M
presionando el atajo de teclado.
Para obtener más detalles sobre cómo obtener un plan de ejecución al usar SQL Server, consulte este artículo .
También puede hacerlo a través de powershell usando SET STATISTICS XML ON para obtener el plan real. Lo escribí para que combine planes de múltiples estados en un solo 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()
Explicar el plan de ejecución puede ser muy detallado y lleva bastante tiempo de lectura, pero en resumen, si usa 'explicar' antes de la consulta, debería proporcionarle mucha información, incluidas las partes que se ejecutaron primero y así. si quieres leer un poco más de detalles sobre esto, compilé un pequeño blog sobre esto que también te indica las referencias correctas. https://medium.com/swlh/jetbrains-datagrip-explain-plan-ac406772c470