扩展事件过滤器的性能影响 [like_i_sql_unicode_string]

dew*_*wet 5 sql-server extended-events sql-server-2012

我创建了一个扩展事件会话,我想在其中查看使用 nolock 提示的所有查询。我决定使用它而不是 sql trace 来最小化可能的性能影响。会话的创建类似于以下语句:

    CREATE EVENT SESSION [SCOMDB_debug] ON SERVER 
    ADD EVENT sqlserver.deprecation_announcement(
        ACTION(sqlserver.client_hostname,sqlserver.database_name,sqlserver.nt_username,sqlserver.session_id,sqlserver.sql_text,sqlserver.transaction_id,sqlserver.username)),
    ADD EVENT sqlserver.rpc_completed(
        ACTION(sqlserver.client_hostname,sqlserver.database_name,sqlserver.nt_username,sqlserver.session_id,sqlserver.sql_text,sqlserver.transaction_id,sqlserver.username)
        WHERE ([sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%NOLOCK%'))),
    ADD EVENT sqlserver.rpc_starting(
        ACTION(sqlserver.client_hostname,sqlserver.database_name,sqlserver.nt_username,sqlserver.session_id,sqlserver.sql_text,sqlserver.transaction_id,sqlserver.username)
        WHERE ([sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%NOLOCK%'))),
    ADD EVENT sqlserver.sp_statement_completed(
        ACTION(sqlserver.client_hostname,sqlserver.database_name,sqlserver.nt_username,sqlserver.session_id,sqlserver.sql_text,sqlserver.transaction_id,sqlserver.username)
        WHERE ([sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%NOLOCK%'))),
    ADD EVENT sqlserver.sp_statement_starting(
        ACTION(sqlserver.client_hostname,sqlserver.database_name,sqlserver.nt_username,sqlserver.session_id,sqlserver.sql_text,sqlserver.transaction_id,sqlserver.username)
        WHERE ([sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%NOLOCK%'))),
    ADD EVENT sqlserver.sql_batch_completed(
        ACTION(sqlserver.client_hostname,sqlserver.database_name,sqlserver.nt_username,sqlserver.session_id,sqlserver.sql_text,sqlserver.transaction_id,sqlserver.username)
        WHERE ([sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%NOLOCK%'))),
    ADD EVENT sqlserver.sql_batch_starting(
        ACTION(sqlserver.client_hostname,sqlserver.database_name,sqlserver.nt_username,sqlserver.session_id,sqlserver.sql_text,sqlserver.transaction_id,sqlserver.username)
        WHERE ([sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%NOLOCK%'))),
    ADD EVENT sqlserver.sql_statement_completed(
        ACTION(sqlserver.client_hostname,sqlserver.database_name,sqlserver.nt_username,sqlserver.session_id,sqlserver.sql_text,sqlserver.transaction_id,sqlserver.username)
        WHERE ([sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%NOLOCK%'))),
    ADD EVENT sqlserver.sql_statement_starting(SET collect_statement=(1)
        ACTION(sqlserver.client_hostname,sqlserver.database_name,sqlserver.nt_username,sqlserver.session_id,sqlserver.sql_text,sqlserver.transaction_id,sqlserver.username)
        WHERE ([sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%NOLOCK%'))) 
    ADD TARGET package0.event_file(SET filename=N'M:\MSSQL11.SCOMDB\MSSQL\Log\SCOMDB_debug.xel',max_file_size=(500))
    WITH (MAX_MEMORY=40960 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=30 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=NONE,TRACK_CAUSALITY=OFF,STARTUP_STATE=OFF)
    GO
Run Code Online (Sandbox Code Playgroud)

结果是数据库实例(用于 SCOM 数据库)变得非常缓慢,应用程序几乎无法使用。

等待统计信息中充满了 SOS_SCHEDULER_YIELD 和 PREEMPTIVE_XE_DISPATCHER,我可以在 sys.dm_exec_requests 中看到许多长时间运行的查询也主要在 CPU 上等待。

这是预期的行为吗?我可以想象 [like_i_sql_unicode_string] 运算符可能会非常消耗性能,但我仍然希望有更好的性能。

ex 事件中是否还有其他过滤器可用于捕获包含“sometext”的查询?

小智 5

我会说你不需要所有的start事件,只需要completed. 我也没有看到您正在为 SCOM 数据库捕获数据。扩展事件可能会导致开销接近 SQL Server 跟踪的开销,具体取决于您尝试捕获的内容。

您基本上是在捕获服务器上遇到的每个查询并告诉它等待,以便您可以首先检查查询的文本,然后通过扩展事件会话获取信息,然后让它完成。

此外,根据环境配置,SCOM 的持续活动很可能会对跟踪或扩展事件造成极端的性能影响。我建议最初查看这些类型查询的计划缓存。但是,您可能会尝试向会话添加更多过滤器,例如仅从活动会话中获取数据样本,然后也仅捕获特定数据库的数据。通过 GUI 看起来像这样:

在此处输入图片说明

或者编码您的WHERE子句将如下所示:

WHERE ((([package0].[divides_by_uint64]([sqlserver].[session_id],(5))) 
   AND ([package0].[greater_than_uint64]([sqlserver].[database_id],(4)))) 
   AND ([package0].[equal_boolean]([sqlserver].[is_system],(0))))) 
Run Code Online (Sandbox Code Playgroud)

这将捕获我认为该数据库在任何给定时间的 20% 的活动会话。但是,如果您想要所有事件,那么您将不得不承受该操作的开销。

由于它是微软产品,我不会关心它产生的查询。如果遇到性能问题,您应该遵循 Microsoft 产品指南或咨询 Microsoft 支持。