在这篇文章中,作者多次运行查询。我注意到逻辑读取在执行过程中略有不同。总共读了几千页,相差2页左右。从上下文来看,我似乎很清楚,在两次之间不会有写活动。如果计划发生变化,我预计会有比零点几分之一更大的变化。
Q:在没有数据写入的情况下,哪些因素会导致SQL Server对同一个查询报告不同的逻辑读取计数?
在这篇文章中,作者多次运行查询。我注意到逻辑读取在执行过程中略有不同。总共读了几千页,相差2页左右。从上下文来看,我似乎很清楚,在两次之间不会有写活动。如果计划发生变化,我预计会有比零点几分之一更大的变化。
Q:在没有数据写入的情况下,哪些因素会导致SQL Server对同一个查询报告不同的逻辑读取计数?
对于堆表,据我所知没有任何机制会导致这种情况。
我注意到作者报告的逻辑读取仅在使用压缩时有所不同。这表明表重建包含在每次执行中。重建语句未指定
MAXDOP = 1
,因此会生成一个并行计划。行在运行时重建中跨线程分布的方式不是确定性的(它取决于时间),因此堆的最终结构会有所不同。这是我能够重现已发布结果的唯一方法。对于聚簇表(或一般的索引结构的查找/扫描),逻辑读取可能因预读活动而异。预读从 b 树的上层读取页面以识别要在扫描之前读取的页面,从而导致不同数量的“额外”逻辑读取,具体取决于存储系统的时间和特性。使用全局跟踪标志 652 禁用预读可用于演示这一点。
我提到预读方面只是为了完整性,因为有问题的表是一个堆。堆扫描确实使用预读,但这是由 IAM 页面驱动的。IAM 页面不构成主表结构的一部分(与 b 树的上层不同),因此这些额外的读取不会由
STATISTICS IO
.