我试图了解我在一个相当大且不守规矩的查询计划中看到的一些行为。特别是,我正在查看在其谓词中包含标量操作的聚簇索引查找操作。我怀疑 Scalar 操作只是其中一个表的别名(如Seek Predicate 中的 Scalar Operator 中所述),因为两列的类型相同,并且此操作馈入并行嵌套循环(左外连接)运算符。
不过,我的问题更多是关于行估计数为 1 而不是更接近实际行数(约 670 万)的数字。标量操作是否会破坏优化器正确估计行的能力?我假设是这样,也假设这会损害我的查询执行计划的最佳状态,但我真的不确定。有人可以证实或反驳我的怀疑以及为什么吗?
这是有问题的操作:
版本:SQL Server 2012 企业版
在嵌套循环连接的内侧,估计的行数表示循环每次迭代的估计值。实际行数是为连接的所有迭代返回的总行数。这是不直观的,也是混淆的常见来源。
我们可以通过一个简单的演示看到这个动作:
聚集索引查找的详细信息
X_INNER_TABLE
:估计行数为 1,因为查找是针对表的完整主键执行的。实际行数为100,因为外表有100行,循环迭代100次,每次循环找到1行。
与您在查询计划中观察到的一样,简单演示中出现了一个类似的标量运算符。您最初的问题没有太多可做的,但标量很可能确实是一条红鲱鱼。相反,我会关注估计执行次数 (580308) 和实际执行次数 (6740779) 之间的差异。SQL Server 估计外表只有它实际拥有的行数的 10%,因此嵌套循环的成本过低。如果优化器对外部表有更准确的基数估计,它可能会从针对该表的嵌套循环连接切换到不同的计划。