15

与常规 JOIN(其中 SQL Server 将决定最佳 JOIN 策略)相比,显式执行 HASH JOIN 有哪些优点(如果有)?例如:

select pd.*
from profiledata pd
inner hash join profiledatavalue val on val.profiledataid=pd.id

在上面的简单示例代码中,我指定了 JOIN 策略,而如果我不使用“hash”关键字,SQL Server 将在后台执行 MERGE JOIN(根据“实际执行计划”)。

4

5 回答 5

15

优化器在日常使用中做得足够好。但是,理论上,极端情况下可能需要 3 周的时间才能找到完美的计划,因此生成的计划有可能并不理想。

除非您有一个非常复杂的查询或大量数据,而它根本无法产生一个好的计划,否则我会不理会它。那我会考虑的。

但是随着时间的推移,随着数据的变化/增长或索引的变化等,您的 JOIN 提示将变得过时并阻止最佳计划。JOIN 提示只能在开发时使用您拥有的那组数据针对该单个查询进行优化。

就个人而言,我从未在任何生产代码中指定 JOIN 提示。

我通常通过更改查询、添加/更改索引或分解它(例如先加载临时表)来解决错误的连接。或者我的查询是错误的,或者我有一个隐式的数据类型转换,或者它突出了我的架构中的一个缺陷等。

我见过其他开发人员使用它们,但仅在复杂视图嵌套在复杂视图上的情况下使用它们,并且在重构时会导致以后出现问题。

编辑:

我今天进行了一次转换,一些同事将使用它们来强制执行错误的查询计划(使用 NOLOCK 和 MAXDOP 1),以“鼓励”从其下游系统之一直接调用的遗留复杂嵌套视图迁移。

于 2009-04-29T04:08:59.173 回答
3

何时尝试哈希提示,如何:

  • 在检查至少一个表上存在足够的索引之后。
  • 在尝试重新安排查询之后。诸如将连接转换为“in”或“exists”、更改连接顺序(无论如何这只是一个提示)、将逻辑从 where 子句移动到连接条件等。

关于哈希连接何时有效的一些基本规则是连接条件不作为表索引存在以及表大小不同时。如果您正在寻找技术描述,那么有一些关于哈希连接如何工作的很好的描述。

为什么要使用任何连接提示(具有强制顺序副作用的哈希/合并/循环)?

  • 为了避免极端情况的执行速度极慢(.5 -> 10.0s)。
  • 当优化器始终选择一个平庸的计划时。

提供的提示在某些情况下可能并不理想,但提供了更一致的可预测运行时。使用提示时,应预先测试预期的最坏情况和最佳情况。可预测的运行时间对于 Web 服务至关重要,例如,严格优化的标称 [.3s, .6s] 查询优于范围 [.25, 10.0s] 的查询。随着统计数据的最新更新和最佳实践的遵循,可能会发生较大的运行时差异。

在开发环境中进行测试时,还应关闭“作弊”以避免热/冷运行时差异。从另一个帖子...

CHECKPOINT -- flushes dirty pages to disk
DBCC DROPCLEANBUFFERS -- clears data cache
DBCC FREEPROCCACHE -- clears execution plan cache

最后一个选项可能与 option(recompile) 提示相同。

机器的 MAXDOP 和加载也会在运行时产生巨大的差异。将 CTE 物化到临时表中也是一种很好的锁定机制,需要考虑。

于 2013-03-20T19:36:57.680 回答
2

哈希联接比任何其他联接都具有更好的并行性和可扩展性,并且非常适合最大化数据仓库中的吞吐量。

于 2009-04-28T23:04:13.290 回答
1

我在运输代码中看到的唯一提示是 OPTION(强制订购)。SQL 查询优化器中的愚蠢错误会生成一个尝试加入未过滤的 varchar 和唯一标识符的计划。添加 FORCE ORDER 导致它首先运行过滤器。

我知道,重载列是不好的。有时,你必须忍受它。

于 2009-04-29T16:57:39.153 回答
0

逻辑计划优化器并不能保证它会找到最佳解决方案:精确算法太慢而无法在生产服务器中使用;取而代之的是一些贪心算法。

因此,这些命令背后的基本原理是让用户指定最佳连接策略,以防优化器无法找出真正最好采用的策略。

于 2009-04-28T23:03:54.540 回答