我可以向扩展事件添加什么以返回正确的 row_counts?

Siy*_*ual 8 sql-server profiler extended-events sql-server-2017

我正在 SQL Server 2017 中运行扩展事件会话,该会话仅记录module_end特定数据库的事件。出现此痕迹的原因有两个:

  1. 我想查看调用存储过程的频率(或缺乏频率)。
  2. 我试图获取每个过程调用的一些细节(例如谁调用它、从哪里调用、花费了多长时间、返回了多少记录等)。

在查看一些结果时,我注意到列表中的一些过程执行了数千万次,但从来没有一次大于row_count0。还有很多其他记录的事件row_count似乎填充正确,因此我最初认为那些从未返回结果的应用程序被引用它们的应用程序错误调用了。然而,事实并非如此。

为了更好地查看调用过程所使用的参数,我启动了一个 Profiler 会话,仅监视这些过程调用。我正在检查的特定过程被非常频繁地调用,并且我很快就收到了大量示例调用,并关闭了探查器。从中注意到以下几点:

  1. 这些调用具有合法的参数。
  2. 在未对扩展事件会话进行任何更改的情况下,在探查器处于活动状态期间记录的过程调用神奇地开始row_count正确记录1为而不是0

以下是我正在使用的扩展事件的定义:

Create Event Session [Test Event] On Server
    Add Event sqlserver.module_end
    (
        Action (sqlserver.database_name, sqlserver.session_id)
        Where
        (
            sqlserver.database_name = N'TestDatabase' 
        And object_type = 'P'
        )
    )
    Add Target package0.ring_buffer (Set max_events_limit = 10000, max_memory = 51200)
    With
    (
        Max_Memory = 4096KB,
        Event_Retention_Mode = Allow_Single_Event_Loss,
        Max_Dispatch_Latency = 30 Seconds,
        Max_Event_Size = 0KB,
        Memory_Partition_Mode = None,
        Track_Causality = On,
        Startup_State = On
    )
Go
Run Code Online (Sandbox Code Playgroud)

以及一些用于测试的示例代码:

Use TestDatabase
Go

Create Table TestTable
(
    ID      Int Not Null Identity (1, 1) Primary Key Clustered,
    Name    Varchar (20)
)
Go

Insert  TestTable (Name)
Values  ('Alpha'), ('Bravo'), ('Charlie'), ('Delta'), ('Echo'), ('Foxtrot'), ('Golf')
Go

Create Procedure GetTestNameByID (@ID Int)
As Begin
    Set NoCount On

    Select  Name
    From    TestTable
    Where   ID = @ID
End
Go

Execute GetTestNameByID @ID = 2
Execute GetTestNameByID @ID = 10
Execute GetTestNameByID @ID = Null
Go

Drop Procedure GetTestNameByID
Drop Table TestTable
Go
Run Code Online (Sandbox Code Playgroud)

注意:我注意到奇怪行为的真实过程在逻辑上等同于上面的测试过程。

运行这三个Execute语句中的每一个都会在扩展事件中产生以下结果:

扩展事件结果

在本例中,row_counts扩展事件中的记录是正确的。然而,在实际环境中,这些都被记录为0,尽管它们实际上是返回结果。

这是我的问题:

  1. 我可以在扩展事件会话中添加一些内容以正确记录row_count
  2. 是否有可能以某种方式调用这些存储过程,它们实际上返回结果,但以某种方式发出0到扩展事件?
  3. 为什么活动的 SQL Profiler 会话会突然使扩展事件会话记录正确的row_count数据?

我想再次强调,扩展事件会话没有发生任何更改,并且在其他存储过程的完全相同的跟踪文件中似乎有正确的结果。

我测试过的其他场景:

  • 从另一个过程中执行存储过程。
  • 从同一服务器上的另一个数据库执行存储过程。
  • 从一个执行存储过程OPENROWSET从不同服务器上的会话
  • 在 a 中执行存储过程,TRANSACTION然后强制ROLLBACK.
  • 在未提交的情况下执行存储过程TRANSACTION.
  • 用于SET NOCOUNT ON
  • 实际后的附加SELECT或声明SETSELECT陈述。
  • 用于OUTPUT在程序中
  • 使用MERGEUPDATE语句。
  • 检查使用情况,发现设置SERVICE BROKER为 时未记录查询。is_systemTrue

当提供有效参数时,所有上述情况都无法产生row_countof 。0@ID

我试图了解它是如何发生的,反过来,也试图找出补救方法。

Zik*_*ato 3

我知道的一种情况是通过 Service Broker Activation 调用该过程。

我能够重现(请注意,我在您的过程中添加了一条额外的语句,以便它返回更多行 - 从值 (1) (2) (3) 中选择)。

在此输入图像描述

请注意,执行激活过程时最后一列is_system为 True。默认情况下不跟踪此列;您必须通过全局字段(操作)添加它