Mengeksekusi kueri dari sini untuk menarik acara kebuntuan dari sesi peristiwa diperpanjang standar
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';
membutuhkan waktu sekitar 20 menit untuk menyelesaikan mesin saya. Statistik yang dilaporkan adalah
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.
Jika saya menghapus WHERE
klausa itu selesai dalam waktu kurang dari satu detik mengembalikan 3,782 baris.
Demikian pula jika saya menambah OPTION (MAXDOP 1)
kueri asli yang mempercepat dengan statistik sekarang menunjukkan lebih sedikit lob dibaca.
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.
Jadi pertanyaan saya adalah
Adakah yang bisa menjelaskan apa yang terjadi? Mengapa rencana awal begitu buruk dan apakah ada cara yang dapat diandalkan untuk menghindari masalah?
Tambahan:
Saya juga menemukan bahwa mengubah kueri untuk INNER HASH JOIN
meningkatkan hal-hal sampai batas tertentu (tapi masih membutuhkan> 3 menit) karena hasil DMV sangat kecil, saya ragu bahwa tipe Bergabung itu sendiri yang bertanggung jawab dan menganggap ada sesuatu yang lain harus berubah. Statistik untuk itu
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.
Setelah mengisi buffer cincin peristiwa diperpanjang ( DATALENGTH
dari XML
4.880.045 byte dan berisi 1.448 peristiwa.) Dan menguji versi pengurangan dari permintaan asli dengan dan tanpa MAXDOP
petunjuk.
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
Memberi hasil berikut
+-------------------------------------+------+----------+
| | 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 |
+-------------------------------------+------+----------+
Ada perbedaan yang jelas dalam alokasi tempdb dengan yang lebih cepat menunjukkan 616
halaman yang dialokasikan dan tidak dialokasikan. Ini adalah jumlah halaman yang sama yang digunakan ketika XML dimasukkan ke dalam variabel juga.
Untuk rencana lambat, jumlah alokasi halaman ini menjadi jutaan. Polling dm_db_task_space_usage
sementara kueri sedang berjalan menunjukkan sepertinya terus-menerus mengalokasikan dan membatalkan alokasi halaman di tempdb
mana saja antara 1.800 dan 3.000 halaman dialokasikan pada satu waktu.
WHERE
klausa ke ekspresi XQuery; logika tidak harus dihapus untuk itu untuk pergi cepat:TargetData.nodes ('RingBufferTarget[1]/event[@name = "xml_deadlock_report"]')
. Yang mengatakan, saya tidak tahu XML internal cukup baik untuk menjawab pertanyaan yang Anda ajukan.