Eseguire la query da qui per estrarre gli eventi deadlock dalla sessione predefinita degli eventi estesi
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';
il completamento della mia macchina richiede circa 20 minuti. Le statistiche riportate sono
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.
Se rimuovo la WHERE
clausola si completa in meno di un secondo restituendo 3.782 righe.
Allo stesso modo se aggiungo OPTION (MAXDOP 1)
alla query originale che accelera anche le cose con le statistiche che ora mostrano un numero enorme di letture lob.
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.
Quindi la mia domanda è
Qualcuno può spiegare cosa sta succedendo? Perché il piano originale è così catastroficamente peggiore e esiste un modo affidabile per evitare il problema?
aggiunta:
Ho anche scoperto che cambiare la query per INNER HASH JOIN
migliorare le cose in una certa misura (ma ci vogliono ancora> 3 minuti) poiché i risultati DMV sono così piccoli che dubito che il tipo Join stesso sia responsabile e presumo che qualcos'altro debba essere cambiato. Statistiche per quello
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.
Dopo aver riempito il buffer eventi estesi anello ( DATALENGTH
della XML
era 4,880,045 byte e conteneva 1.448 eventi.) E test di un taglio giù versione della query originale con e senza il MAXDOP
suggerimento.
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
Ha dato i seguenti risultati
+-------------------------------------+------+----------+
| | 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 |
+-------------------------------------+------+----------+
C'è una chiara differenza nelle allocazioni tempdb con quella più veloce che mostra le 616
pagine allocate e deallocate. Questa è la stessa quantità di pagine utilizzate quando anche l'XML viene inserito in una variabile.
Per il piano lento, questi conteggi di allocazione delle pagine sono in milioni. Il polling dm_db_task_space_usage
mentre la query è in esecuzione mostra che sembra che stia allocando e deallocando costantemente le pagine in tempdb
qualsiasi momento tra 1.800 e 3.000 pagine allocate contemporaneamente.
WHERE
clausola nell'espressione XQuery; la logica non deve essere rimosso per poter andare veloce:TargetData.nodes ('RingBufferTarget[1]/event[@name = "xml_deadlock_report"]')
. Detto questo, non conosco abbastanza bene gli interni XML per rispondere alla domanda che hai posto.