Ejecutar la consulta desde aquí para extraer los eventos de punto muerto de la sesión de eventos extendidos predeterminada
SELECT CAST (
REPLACE (
REPLACE (
XEventData.XEvent.value ('(data/value)[1]', 'varchar(max)'),
'<victim-list>', '<deadlock><victim-list>'),
'<process-list>', '</victim-list><process-list>')
AS XML) AS DeadlockGraph
FROM (SELECT CAST (target_data AS XML) AS TargetData
FROM sys.dm_xe_session_targets st
JOIN sys.dm_xe_sessions s ON s.address = st.event_session_address
WHERE [name] = 'system_health') AS Data
CROSS APPLY TargetData.nodes ('//RingBufferTarget/event') AS XEventData (XEvent)
WHERE XEventData.XEvent.value('@name', 'varchar(4000)') = 'xml_deadlock_report';
Tarda unos 20 minutos en completarse en mi máquina. Las estadísticas reportadas son
Table 'Worktable'. Scan count 0, logical reads 68121, physical reads 0, read-ahead reads 0,
lob logical reads 25674576, lob physical reads 0, lob read-ahead reads 4332386.
SQL Server Execution Times:
CPU time = 1241269 ms, elapsed time = 1244082 ms.
Si elimino la WHERE
cláusula, se completa en menos de un segundo y devuelve 3.782 filas.
Del mismo modo, si agrego OPTION (MAXDOP 1)
a la consulta original, eso también acelera las cosas con las estadísticas que ahora muestran muchísimo menos lecturas de lóbulos.
Table 'Worktable'. Scan count 0, logical reads 15, physical reads 0, read-ahead reads 0,
lob logical reads 6767, lob physical reads 0, lob read-ahead reads 6076.
SQL Server Execution Times:
CPU time = 639 ms, elapsed time = 693 ms.
Entonces mi pregunta es
¿Alguien puede explicar lo que está pasando? ¿Por qué el plan original es tan catastróficamente peor y hay alguna forma confiable de evitar el problema?
Adición:
También descubrí que cambiar la consulta para INNER HASH JOIN
mejorar las cosas hasta cierto punto (pero aún toma más de 3 minutos) ya que los resultados del DMV son tan pequeños que dudo que el tipo de unión en sí sea responsable y supongo que algo más debe haber cambiado. Estadísticas para eso
Table 'Worktable'. Scan count 0, logical reads 30294, physical reads 0, read-ahead reads 0,
lob logical reads 10741863, lob physical reads 0, lob read-ahead reads 4361042.
SQL Server Execution Times:
CPU time = 200914 ms, elapsed time = 203614 ms.
Después de llenar el búfer de anillo de eventos extendidos ( DATALENGTH
de XML
4,880,045 bytes y contenía 1,448 eventos) y probar una versión reducida de la consulta original con y sin la MAXDOP
sugerencia.
SELECT COUNT(*)
FROM (SELECT CAST (target_data AS XML) AS TargetData
FROM sys.dm_xe_session_targets st
JOIN sys.dm_xe_sessions s
ON s.address = st.event_session_address
WHERE [name] = 'system_health') AS Data
CROSS APPLY TargetData.nodes ('//RingBufferTarget/event') AS XEventData (XEvent)
WHERE XEventData.XEvent.value('@name', 'varchar(4000)') = 'xml_deadlock_report'
SELECT*
FROM sys.dm_db_task_space_usage
WHERE session_id = @@SPID
Dio los siguientes resultados
+-------------------------------------+------+----------+
| | Fast | Slow |
+-------------------------------------+------+----------+
| internal_objects_alloc_page_count | 616 | 1761272 |
| internal_objects_dealloc_page_count | 616 | 1761272 |
| elapsed time (ms) | 428 | 398481 |
| lob logical reads | 8390 | 12784196 |
+-------------------------------------+------+----------+
Hay una clara diferencia en las asignaciones tempdb con la más rápida que muestra las 616
páginas asignadas y desasignadas. Esta es la misma cantidad de páginas utilizadas cuando el XML también se coloca en una variable.
Para el plan lento, estos recuentos de asignación de páginas están en millones. El sondeo dm_db_task_space_usage
mientras se ejecuta la consulta muestra que parece estar constantemente asignando y desasignando páginas tempdb
con entre 1.800 y 3.000 páginas asignadas en cualquier momento.
WHERE
cláusula a la expresión XQuery; la lógica no tiene que ser eliminado para que vaya rápido:TargetData.nodes ('RingBufferTarget[1]/event[@name = "xml_deadlock_report"]')
. Dicho esto, no conozco los componentes internos de XML lo suficientemente bien como para responder la pregunta que ha planteado.