我已经执行了一个查询并包含了实际执行计划。有一个我感兴趣的哈希匹配,因为它的子树使用索引扫描而不是索引搜索。当我将鼠标悬停在这个哈希匹配上时,有一个名为“Probe Residual”的部分。我曾假设这是我加入的任何价值观。我在这里是正确的还是对这意味着什么有更好的解释?
我遇到的第二个问题是关于它使用的索引。在我的示例中,我很确定这个特定的连接是在两列上连接的。它正在扫描的索引中包含这两个列以及连接中未使用的另一列。我的印象是,这将导致 Index Seek 而不是 Scan。我错了吗?
我已经执行了一个查询并包含了实际执行计划。有一个我感兴趣的哈希匹配,因为它的子树使用索引扫描而不是索引搜索。当我将鼠标悬停在这个哈希匹配上时,有一个名为“Probe Residual”的部分。我曾假设这是我加入的任何价值观。我在这里是正确的还是对这意味着什么有更好的解释?
我遇到的第二个问题是关于它使用的索引。在我的示例中,我很确定这个特定的连接是在两列上连接的。它正在扫描的索引中包含这两个列以及连接中未使用的另一列。我的印象是,这将导致 Index Seek 而不是 Scan。我错了吗?
至于您的第二个,优化器可能会在多种情况下选择索引扫描。在我的头顶上:
如果索引中的大部分行将被查询选中
如果您在查询的 where 子句中使用函数
对于前两种情况,进行扫描更有效,因此优化器选择它而不是搜索。对于第三种情况,优化器别无选择。
哈希连接通常(总是?)使用扫描或至少使用范围扫描。散列连接的工作原理是扫描左连接表和右连接表(或表中的范围)并构建一个内存中的哈希表,其中包含扫描“看到”的所有值。
在您的情况下发生的情况是这样的:QO 注意到它可以从恰好包含该列(作为键或作为包含列)的非聚集索引中获取列 C 的所有值。作为一个非聚集索引可能相当狭窄,因此扫描整个非聚集索引的 IO 总量并不夸张。QO 还认为系统有足够的 RAM 在内存中存储哈希表。当将此查询的成本(例如,10000 页的非聚集索引端到端扫描)与使用搜索的嵌套循环的成本(例如 5000 次探测,每次 2-3 页)进行比较时,扫描因需要较少的 IO 而获胜。当然,这在很大程度上是我的猜测,但我试图从 QO 的角度来介绍这个案例,并且该计划可能是最优的。
促成这一特定计划选择的因素是:
对于候选数量的大量估计,比散列连接更好的选择只是合并连接,并且需要对输入进行预排序。如果左侧都可以提供保证连接列上的顺序的访问路径,并且右侧具有类似的可能性,那么您最终可能会使用合并连接,这是最快的连接。
1/ 哈希匹配意味着它采用相等连接中使用的列的哈希,但需要包括连接中涉及的所有其他列(for > 等),以便也可以检查它们。这就是残差列的用武之地。
2/ 如果可以直接找到您想要的行,则可以完成索引搜索。也许您正在对列应用计算并使用它?然后它将使用索引作为数据的较小版本,但仍需要检查每一行(对每一行应用计算)。
查看 simple-talk.com 上关于执行计划的优秀文章:
他们还有免费的电子书SQL Server 执行计划供下载。