Ausführen der Abfrage von hier aus , um die Deadlock-Ereignisse aus der erweiterten Standardereignissitzung zu entfernen
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';
Die Ausführung auf meinem Computer dauert ungefähr 20 Minuten. Die gemeldeten Statistiken sind
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.
Wenn ich die WHERE
Klausel entferne , wird sie in weniger als einer Sekunde abgeschlossen und liefert 3.782 Zeilen.
Ebenso, wenn ich OPTION (MAXDOP 1)
zu der ursprünglichen Abfrage hinzufüge , die die Dinge auch mit den Statistiken beschleunigt, die jetzt massiv weniger Lob-Lesevorgänge anzeigen.
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.
Also meine Frage ist
Kann jemand erklären, was los ist? Warum ist der ursprüngliche Plan so katastrophal und gibt es eine verlässliche Möglichkeit, das Problem zu umgehen?
Zusatz:
Ich habe auch festgestellt, dass das Ändern der Abfrage INNER HASH JOIN
die Dinge in gewissem Maße verbessert (aber es dauert immer noch> 3 Minuten), da die DMV-Ergebnisse so klein sind, dass ich bezweifle, dass der Join-Typ selbst dafür verantwortlich ist und davon ausgeht, dass sich etwas anderes geändert hat. Statistiken dafür
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.
Nach dem Auffüllen des erweiterten Ereignisringpuffers ( DATALENGTH
der XML
4.880.045 Byte enthielt und 1.448 Ereignisse enthielt) und dem Testen einer gekürzten Version der ursprünglichen Abfrage mit und ohne MAXDOP
Hinweis.
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
Ergab die folgenden Ergebnisse
+-------------------------------------+------+----------+
| | 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 |
+-------------------------------------+------+----------+
Es gibt einen deutlichen Unterschied in der Zuweisung von Tempdb zu der schnelleren, die anzeigt, dass 616
Seiten zugewiesen und freigegeben wurden. Dies ist die gleiche Anzahl von Seiten, die verwendet werden, wenn das XML auch in eine Variable eingefügt wird.
Für den langsamen Plan liegen diese Seitenzuordnungszahlen in Millionenhöhe. Die Abfrage dm_db_task_space_usage
während der Ausführung der Abfrage zeigt, dass ständig tempdb
Seiten zugewiesen und freigegeben werden, wobei zwischen 1.800 und 3.000 Seiten gleichzeitig zugewiesen werden.
WHERE
Klausel in den XQuery-Ausdruck verschieben. die Logik muss nicht entfernt werden , damit es schnell gehen:TargetData.nodes ('RingBufferTarget[1]/event[@name = "xml_deadlock_report"]')
. Trotzdem kenne ich XML-Interna nicht gut genug, um die von Ihnen gestellte Frage zu beantworten.