观察使用 Live Query Statistics 执行的查询,我注意到SQL Server似乎正在从散列连接的构建输入中懒惰地构建散列表。
在 0 个探测行的情况下,这是一个有意义的差异。它可能会保存整个构建端树。
我一直认为哈希是这样运行的:
- 创建构建端哈希表。
- 将所有探测行与其匹配。
但它是下面的吗?
- 拉第一个探针行。
- 如果没有行可用(短路),则完成操作。
- 将所有探测行与其匹配。
我不确定如何最终测试它是哪种方式。我不确定以这种方式可以信任实时查询统计输出。有谁知道这是如何工作的?
如果您发布特定查询的实际查询计划,我们也许可以更直接地对此发表评论。
但总的来说,我相信(并且一直观察到)散列连接运算符确实总是按您预期的方式运行:
这通常是有意义的,因为 SQL Server 会将较小的(估计的)行集放在连接的构建端。探测端预计比构建端大(因此至少包含一些行)。
此外,SQL Server 有一个潜在的位图优化,它可以在某些情况下应用于散列连接的探测端,但此优化要求首先处理构建端。
一个例子
对于一个简单的查询,我们强制在散列连接的大型构建端和一个空的探测端,实际执行计划显示所有行都在连接的构建端处理。
可以跳过构建端吗?
至少有一个示例可以跳过散列连接的构建端:在某些情况下,可以消除整个连接。例如,这里 SQL Server 能够在执行之前证明探测端将有 0 行。因此最终的查询计划是一个持续的扫描,没有散列连接。
批处理模式呢?
基于快速测试,批处理模式散列连接运算符似乎也将完全处理散列连接的构建端。