可视化 SQL Server 扩展事件数据

Lev*_*lho 17 sql-server extended-events

最近,我一直在探索使用 SQL Server 中的扩展事件来帮助我对各种查询进行基准测试和优化。到目前为止,为了查看事件数据,我一直在使用 SSMS 中的“观看实时数据”功能。

我遇到的问题是 Live Events 功能似乎使用了内部缓冲区,这意味着有时我需要多次执行查询才能使其信息显示在窗口中。因此,我有一个由两部分组成的问题要问:

  1. 有没有办法解决这种延迟,让事件显示在实时提要中?(我在本地数据库上执行此操作,因此性能不是问题)
  2. 实时提要是可视化扩展事件数据的最佳方式吗?SSMS 中是否有其他工具更适合我的用例?

更新

根据要求,这里是会话:

CREATE EVENT SESSION [Simple Query Benchmarking] ON SERVER 
ADD EVENT sqlserver.sql_batch_completed(SET collect_batch_text=(1)
    ACTION(sqlserver.query_hash,sqlserver.query_plan_hash,sqlserver.sql_text)
    WHERE ([package0].[equal_boolean]([sqlserver].[is_system],(0)) AND [package0].[greater_than_uint64]([duration],(1000)))) 
ADD TARGET package0.ring_buffer
WITH (MAX_MEMORY=4096 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=1 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=NONE,TRACK_CAUSALITY=ON,STARTUP_STATE=OFF)
GO
Run Code Online (Sandbox Code Playgroud)

小智 16

警告:下面提供的大部分信息都是我从Jonathan Keyhayias 的两门 Pluralsight 课程中学到的。值得花费一个月的费用来学习他的两门课程。

首先是一些我认为会有所帮助(或至多是有趣的)的兴趣点:

  • 当一个扩展事件会话开始时,它将有一部分内存分配给一个缓冲区空间来存储由会话事件生成的数据。在您的会话中,这被设置为默认值 4MB
  • 有多个目标可供使用。这些目标要么synchronous或者asynchronous他们是如何接收数据。两个最常用的目标是目标文件和环形缓冲区都是异步的。这里的 BOL 文章指出了每个目标的类型
  • MAX_DISPATCH_LATENCY是一个配置选项,用于控制何时将事件数据分派到目标。分派只发生在异步目标上。有两种情况会导致事件数据被分派:(1) 会话的内存缓冲区已满或 (2) 缓冲区中的事件数据超出了会话的MAX_DISPATCH_LATENCY配置选项。
  • 当您打开实时数据查看器时,它会将一个额外的目标附加到名为“流目标”的事件会话中。这将在调度内存缓冲区时接收实时事件流。它实际上还将与会话相关的调度延迟更改为 3 秒,以便获得接近实时的会话视图。

现在谈谈您问题中的具体要点:

我遇到的问题是 Live Events 功能似乎使用了内部缓冲区,这意味着有时我需要多次执行查询才能使其信息显示在窗口中。因此,我有一个由两部分组成的问题要问

除了我上面所说的,我不知道它会这样做。我希望事件被捕获它只是不满足将其分派到您的实时数据查看器所需的阈值。我使用以下查询对此进行了测试AdventureWorks2012

SELECT * FROM dbo.ErrorLog
WAITFOR DELAY '00:00:01' ;
GO
Run Code Online (Sandbox Code Playgroud)

使用您的事件会话配置,除了我过滤以仅捕获AdventureWorks2012本地实例上数据库的数据外,我可以查看此会话的目标数据并发现查询已捕获:

在此处输入图片说明 在此处输入图片说明

再执行一次此查询将最终导致它被调度并且数据查看器显示一个事件。现在,如果您真的想查看显示的所有事件,只需STOP会话和缓冲区将被完全调度。一旦我停止会话,我就会看到这一点:

在此处输入图片说明

1.有没有办法解决这种延迟,让事件显示在实时提要中?(我在本地数据库上执行此操作,因此性能不是问题)

我原以为您可以将 the 更改MAX_MEMORY为较低的值,这将指示较小的缓冲区大小来捕获事件。但是,您可以在 SQL Server 2012 中将此设置为的最低值是200KB,我使用的查询不符合该限制以使其立即被分派。我唯一能做的就是最多执行一个查询,该查询将导致到达缓冲区并调度捕获的先前事件:

SELECT *
FROM Person.Person
ORDER BY EmailPromotion DESC;
Run Code Online (Sandbox Code Playgroud)

2.实时提要是可视化扩展事件数据的最佳方式吗?SSMS 中是否有其他工具更适合我的用例?

不是我目前知道的。我建议在数据发生时立即获取数据的最佳方法是查询ring_buffer目标的 XML并将其切碎。我可以重复上面的例子,只要我执行下面的查询,我就会看到事件。

-- Create XML variable to hold Target Data
DECLARE @target_data XML
SELECT  @target_data = CAST([t].[target_data] AS XML)
FROM    [sys].[dm_xe_sessions] AS s
JOIN    [sys].[dm_xe_session_targets] AS t
        ON [t].[event_session_address] = [s].[address]
WHERE   [s].[name] = N'Simple Query Benchmarking' AND
        [t].[target_name] = N'ring_buffer' ;

-- Return the full XML document
--SELECT @target_data;

--Shred XMl to get needed data
SELECT  DATEADD(hh, DATEDIFF(hh, GETUTCDATE(), CURRENT_TIMESTAMP), n.value('(@timestamp)[1]', 'datetime2')) AS [timestamp],
    n.value('(data[@name="duration"]/value)[1]', 'bigint') as duration,
    n.value('(action[@name="sql_text"]/value)[1]', 'varchar(max)') as sql_text
FROM @target_data.nodes('RingBufferTarget/event[@name=''sql_batch_completed'']') AS q(n)
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

  • 很好的答案,非常详细。只是点,它比任何真正的讨论都更有趣;你提到了 Johnathan Kehayias,我同意,他的 Pluralsight 课程 100% 值得 1 个月的费用。然而,他有一个博客,在那里他谈到了他是如何**讨厌** Ring Buffer 目标的。它是从 2014 年开始的,所以现在可能已经改变了,但这是一个有趣的阅读:https://www.sqlskills.com/blogs/jonathan/why-i-hate-the-ring_buffer-target-in-extended-events/ (3认同)