无法运行查询以及时获取死锁图

And*_*dén 3 sql-server deadlock

我正在尝试使用此查询从 sql-server 获取死锁信息

select XEventData.XEvent.value('(data/value)[1]', 'varchar(max)') 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'
Run Code Online (Sandbox Code Playgroud)

然而,查询需要永远并返回一个空结果。

为什么需要这么长时间,并且您从该视图中获得的死锁信息是否具有追溯力,以便我能够查明前段时间发生的死锁?

Eri*_*ing 8

为什么需要很长时间?

查询 XML 时必须非常小心。您的查询在这方面有点灾难,特别是这部分:where XEventData.XEvent.value('@name', 'varchar(4000)') = 'xml_deadlock_report'

这导致一大堆 XML 被拖来拖去,加入,然后过滤:

坚果

使用exists方法会更好,如下所示:

SELECT
    DeadlockGraph = 
        XEventData.XEvent.value('(data/value)[1]', 'varchar(max)')
FROM
(
    SELECT
        TargetData = CONVERT(xml, st.target_data)
    FROM sys.dm_xe_session_targets AS st
    JOIN sys.dm_xe_sessions AS s
        ON s.address = st.event_session_address
    WHERE s.name = 'system_health'
) AS Data
CROSS APPLY TargetData.nodes('//RingBufferTarget/event') AS XEventData(XEvent)
WHERE XEventData.XEvent.exist('/event/@name[ .= "xml_deadlock_report"]') = 1;
Run Code Online (Sandbox Code Playgroud)

XML 过滤仍然有点笨拙,但它在执行计划中发生得更早。

您可能还会发现首先将转换后的 XML 放入#temp表中是有益的,这样 XML 结构的验证只需进行一次。

SELECT
    TargetData = 
        CONVERT(xml, st.target_data)
INTO #x
FROM sys.dm_xe_session_targets AS st
JOIN sys.dm_xe_sessions AS s
    ON s.address = st.event_session_address
WHERE s.name = 'system_health';

SELECT
    DeadlockGraph = 
        XEventData.XEvent.value('(data/value)[1]', 'varchar(max)')
FROM
(
    SELECT
        TargetData
    FROM #x
) AS Data
CROSS APPLY TargetData.nodes('//RingBufferTarget/event') AS XEventData(XEvent)
WHERE XEventData.XEvent.exist('/event/@name[ .= "xml_deadlock_report"]') = 1;
Run Code Online (Sandbox Code Playgroud)

如果您想要替代方案,您可能会发现sp_BlitzLock很有用。

视图是否具有追溯力?

只能靠运气了。数据的大小是有限制的,如果记录了很多事件,它们可能会推出有用的死锁数据。您可以编辑会话,正如Aaron Betrand 在此博客文章中所述

如果您对死锁特别感兴趣,最好的办法是为此专门设置一个扩展的事件会话。