为什么窗口聚合函数的逻辑读取量很高?
在执行计划中使用公共子表达式假脱机时,逻辑读取往往会显着增加对于更大的桌子。经过实验和观察执行计划,发现以下公式似乎成立:
工作表逻辑读取 = 1 NumberOfRows 2 NumberOfGroups 4
然而,这个公式的根本原因仍不清楚。本文旨在揭开逻辑读取计算背后的谜团。
理解窗口聚合函数执行
计划开始时的段迭代器会向行附加一个标志指示每个新分区的开始。随后,主段假脱机每次检索一行并将它们插入到 tempdb 工作表中。遇到新的组标志时,假脱机将一行返回到嵌套循环运算符的上部输入。
这会触发工作表行上的流聚合,计算平均值。然后将计算出的平均值与工作表行连接,并截断工作表以准备下一组。 Segment spool 生成一个虚拟行来处理最后的组。
工作表的逻辑读取计算
根据我们的理解,工作表是一个堆(或索引假脱机)如果计划中另有规定)。在提供的示例中,与预期相反,仅需要 11 次逻辑读取。对于这种差异的解释如下:
这使逻辑读取总数达到 4 x 3 = 12,省略了触发逻辑读取的第四行的插入只在原作中
结论
理解这个公式的关键在于工作表和常规假脱机表的逻辑读取计数之间的差异。对于工作表,读取的每一行都被计为一次逻辑读取,而对于假脱机表,每个散列页都被计数。
该公式与观察到的执行情况一致:两个辅助假脱机被读取两次(2 COUNT ()),而主线轴发出 (COUNT(DISTINCT CustomerID) 1) 行,如附加信息中提到的博客条目中所述。额外的一个是由于发出额外的行来指示最后一组的结束。
以上是为什么窗口聚合函数会导致 SQL Server 中如此高的逻辑读取?的详细内容。更多信息请关注PHP中文网其他相关文章!