SQL Server Profiler 中的 RowCounts 是如何计算的?

D.S*_*.S. 5 sql-server profiler sql-server-2014

我有一个问题,其中RowCountsaSP:StmtCompleted中的列返回的计数与为执行 select 语句而返回的实际行不同。

select @@RowCount在 select 查询之后尝试了 a ,它返回的计数与count(*). 我现在很好奇是什么导致分析器返回不正确的行数。

我确实阅读了相关线程,表明碎片化可能会产生错误的计数并且DBCC UPDATEUSAGE可能会解决问题,但我想在应用它之前了解我在做什么。我将不胜感激。另外,索引是否在计数中起作用?

相关问答:SQL Server Row Count sp_spaceused rows 差异

我正在使用 SQL Server 2014 Profiler。

这是您在 Profiler 中查看行计数的方式,以防万一有人想知道:在 SQL Profiler 中显示行计数

Pau*_*ite 8

通常,您可以预期报告的行数将对应于返回给调用者的行数(以及(x row(s) affected)在顶级查询的情况下 SQL Server Management Studio 中的消息)。

但是,如果语句包含嵌套调用,例如对标量用户定义函数的调用,则在对函数执行计划的(重复)调用中生成的行计数将被添加到总数中。这是计数完成位置的不幸副作用*,以及当前实现非内联函数的方式。它被认为不够重要来修复

在链接的连接项示例(在Guy Glanster的父博客文章中更好地格式化)中,返回 100 行的查询的总行数报告为 300,这是由于函数中的两个语句中的每一个都影响了单行, 在每次调用时。

如果将函数简化为单个语句:

RETURN CAST(@DateTimeValue AS date);
Run Code Online (Sandbox Code Playgroud)

...计数为 200(外部查询为 100 行,该函数为 1 行一百次)。

DBCC UPDATEUSAGE不会影响这个。索引和碎片也没有关系。这只是一个架构结果,也是避免非内联函数的另一个原因。


* 细节相当深奥。从广义上讲,对于SELECT查询,它是在计划的根节点处看到的行数。涉及到共享内存结构,您在执行计划中无法直接看到任何内容。当标量函数执行时,它会在恰好共享结构的子上下文中执行。也许这是设计使然,没有源代码访问很难确定。我的感觉(如上所述)是一种意想不到的副作用。对于 DML 查询,特定的计划节点被分配了维护受影响行数的工作。这可能会因计划的形状而显着不同(例如,如果使用OUTPUT子句,或使用拆分折叠更新处理)。