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