从 SQL Server 2008 开始的From Clause Documentation简要提到了 3 种连接提示及其基本机制:
- 减少
- 复制
- 重新分配
然而,似乎没有太多关于何时可能需要使用它们的信息。
看来它们可以与散列、循环和合并结合使用,这些已经为这个问题的目的而被理解。
文档中的相关部分:
对于 SQL 数据仓库和并行数据仓库,这些连接提示适用于两个分布不兼容列上的内部连接。它们可以通过限制查询处理期间发生的数据移动量来提高查询性能。SQL 数据仓库和并行数据仓库允许的连接提示如下:
REDUCE
减少连接右侧表要移动的行数,以使两个分布不兼容的表兼容。REDUCE 提示也称为半连接提示。REPLICATE
将连接左侧表的连接列中的值复制到所有节点。右边的表连接到这些列的复制版本。REDISTRIBUTE
强制将两个数据源分布在 JOIN 子句中指定的列上。对于分布式表,并行数据仓库将执行随机移动。对于复制表,并行数据仓库将执行修剪移动。要了解这些移动类型,请参阅并行数据仓库产品文档中“了解查询计划”主题中的“DMS 查询计划操作”部分。当查询计划使用广播移动来解决分布不兼容的连接时,此提示可以提高性能。
一般而言,我们使用连接提示是为了纠正优化器的失败,以确定更好的查询计划。发生这种情况的原因有很多,大致归结为优化是一种“足够好”的方法,受限于寻找计划的时间预算。
减少
“也称为半连接提示”。使用半连接,我们只对另一个表中是否存在任何匹配行感兴趣。实际上,这通常是因为查询具有 EXISTS() 谓词。如果有一个匹配项或一百万个匹配项,结果将是相同的 - 将返回左侧(外部)表中的单行。
例如,我们可能想查询所有曾经下过订单的客户。假设 Customer 是一张小表,但 Order 很大并且分布在许多节点上。当我们只需要知道每个客户是否至少存在一行时,将所有数据复制到客户所在的任何地方是一种浪费。REDUCE 提示提供了这一点。从概念上讲,它
select distinct CustomerId from Order
在每个持有 Order 的节点上运行,速度相对较快。复制
这是 REDUCE 的逆过程。在这里,一个表从它的“主”节点被整体复制到所有节点,这些节点包含连接右侧表中的数据。
对于此示例,我们需要所有订单的总价值,按客户城市求和。我们只有相对较少的客户可以轻松地适应单个节点。然而,Orders 表非常庞大并且跨越许多节点。为了满足查询,我们必须将客户和订单数据都放到同一个节点上。复制 Customer 会更有效率,因为它更小。REPLICATE 提示强制执行该行为,在每个包含订单行的节点上制作 Customer 表的完整副本。
重新分配
这是说明应如何将行从其“主”节点移动到另一个节点以便评估连接谓词的另一种方式。这次我们要求服务器复制数据并根据一些新的分布函数分发该副本,以便复制的行最终位于正确的节点上以完成连接。
假设现在我们有一个零售电子商务网站,有很多客户和很多订单。客户按 CustomerId 分配,订单按 OrderDate 分配。如果我们现在想要
join on Customer.CustomerId = Order.CustomerId
最高效的方案可能是复制Order并根据CustomerId重新分配,然后将每个新分区传递给相应的节点。这与 REPLICATE 不同,因为整个表被复制到每个节点,而这里每个节点的数据的一部分被复制到其他节点。处理重新分配的具体方式将取决于当前分配和基数。