Exécution de la requête à partir d'ici pour extraire les événements d'interblocage de la session d'événements étendus par défaut
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';
prend environ 20 minutes à compléter sur ma machine. Les statistiques rapportées sont
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 je supprime la WHERE
clause, elle se termine en moins d’une seconde et renvoie 3 782 lignes.
De la même manière, si j'ajoute OPTION (MAXDOP 1)
à la requête initiale une accélération du processus, les statistiques affichent désormais un nombre de lectures massivement moins élevé.
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.
Donc ma question est
Quelqu'un peut-il expliquer ce qui se passe? Pourquoi le plan initial est-il si catastrophiquement pire et existe-t-il un moyen fiable d'éviter le problème?
Une addition:
J'ai également constaté que modifier la requête INNER HASH JOIN
améliore quelque peu les choses (mais cela prend toujours plus de 3 minutes) car les résultats DMV sont si petits que je doute que le type de jointure lui-même soit responsable et présume que quelque chose d'autre doit avoir changé. Statistiques pour ça
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.
Après avoir rempli le tampon DATALENGTH
d’ XML
annonce des événements étendus (4 880 045 octets, contenant 1448 événements), et testé une version réduite de la requête initiale avec et sans MAXDOP
indication.
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
A donné les résultats suivants
+-------------------------------------+------+----------+
| | 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 |
+-------------------------------------+------+----------+
Il existe une nette différence dans les allocations de tempdb, la plus rapide montrant que les 616
pages ont été allouées et désallouées. Cela correspond au même nombre de pages utilisées lorsque le XML est également placé dans une variable.
Pour le plan lent, ces comptes d'allocation de pages se chiffrent en millions. Le fait de scruter dm_db_task_space_usage
pendant que la requête est en cours montre qu’il semble allouer et désallouer en permanence des pages, tempdb
avec entre 1 800 et 3 000 pages allouées à la fois.
WHERE
clause dans l'expression XQuery. la logique ne doit pas être supprimé car pour aller vite:TargetData.nodes ('RingBufferTarget[1]/event[@name = "xml_deadlock_report"]')
. Cela dit, je ne connais pas suffisamment bien les composants internes XML pour répondre à la question que vous avez posée.