指定 HASH JOIN 比仅执行 JOIN 的优势?
Posted
技术标签:
【中文标题】指定 HASH JOIN 比仅执行 JOIN 的优势?【英文标题】:advantages in specifying HASH JOIN over just doing a JOIN? 【发布时间】:2010-10-22 10:57:20 【问题描述】:与常规 JOIN 相比,显式执行 HASH JOIN(其中 SQL Server 将决定最佳 JOIN 策略)有哪些优势(如果有)?例如:
select pd.*
from profiledata pd
inner hash join profiledatavalue val on val.profiledataid=pd.id
在上面的简单示例代码中,我指定了 JOIN 策略,而如果我不使用“hash”关键字,SQL Server 将在后台执行 MERGE JOIN(根据“实际执行计划”)。
【问题讨论】:
【参考方案1】:优化器在日常使用中做得足够好。但是,理论上可能需要 3 周的时间才能找到最完美的计划,因此生成的计划可能并不理想。
除非您有一个非常复杂的查询或大量数据,而它根本无法产生一个好的计划,否则我会不理会它。那我会考虑的。
但是随着时间的推移,随着数据的变化/增长或索引的变化等,您的 JOIN 提示将变得过时并阻止最佳计划。 JOIN 提示只能在开发时使用您拥有的那组数据针对单个查询进行优化。
就我个人而言,我从未在任何生产代码中指定 JOIN 提示。
我通常通过更改查询、添加/更改索引或分解它(例如先加载临时表)来解决错误的连接。或者我的查询是错误的,或者我有一个隐式的数据类型转换,或者它突出了我的架构中的一个缺陷等。
我见过其他开发人员使用它们,但仅在复杂视图嵌套在复杂视图上的情况下使用它们,并且在重构时会导致以后出现问题。
编辑:
我今天进行了一次转换,一些同事将使用它们来强制执行错误的查询计划(使用 NOLOCK 和 MAXDOP 1),以“鼓励”从其下游系统之一直接调用的遗留复杂嵌套视图迁移。
【讨论】:
【参考方案2】:何时尝试哈希提示,如何:
在检查至少一个上存在足够的索引后 表格。 尝试重新安排查询后。转换之类的事情 加入“in”或“exists”,改变加入顺序(这只是一个真正的 无论如何提示),将逻辑从 where 子句移动到连接条件等。关于哈希连接何时有效的一些基本规则是连接条件不作为表索引存在以及表大小不同时。如果您正在寻找技术描述,那么有一些关于哈希连接如何工作的很好的描述。
为什么要使用任何连接提示(具有强制顺序副作用的哈希/合并/循环)?
为了避免极端情况的执行速度极慢(0.5 -> 10.0s)。 当优化器始终选择一个平庸的计划时。提供的提示在某些情况下可能并不理想,但提供更一致的可预测运行时。使用提示时,应预先测试预期的最坏情况和最佳情况。可预测的运行时间对于 Web 服务至关重要,例如,严格优化的标称 [.3s, .6s] 查询优于范围 [.25, 10.0s] 的查询。随着统计数据的最新更新和最佳实践的遵循,可能会发生较大的运行时差异。
在开发环境中进行测试时,还应关闭“作弊”以避免热/冷运行时差异。来自另一个post...
CHECKPOINT -- flushes dirty pages to disk
DBCC DROPCLEANBUFFERS -- clears data cache
DBCC FREEPROCCACHE -- clears execution plan cache
最后一个选项可能与 option(recompile) 提示相同。
机器的 MAXDOP 和加载也会在运行时产生巨大的差异。将 CTE 物化到临时表中也是一种很好的锁定机制,需要考虑。
【讨论】:
【参考方案3】:哈希联接比任何其他联接都具有更好的并行性和可扩展性,并且非常适合最大限度地提高数据仓库的吞吐量。
【讨论】:
【参考方案4】:我在运输代码中看到的唯一提示是 OPTION (FORCE ORDER)。 SQL 查询优化器中的愚蠢错误会生成一个尝试加入未过滤的 varchar 和唯一标识符的计划。添加 FORCE ORDER 会导致它首先运行过滤器。
我知道,重载列是不好的。有时,你必须忍受它。
【讨论】:
编辑我即将添加一个 OPTION (MAXDOP 1) 以防止后台工作人员消耗所有处理器能力。【参考方案5】:逻辑计划优化器并不能保证它会找到最佳解决方案:精确算法太慢而无法在生产服务器中使用;而是使用了一些贪心算法。
因此,这些命令背后的基本原理是让用户指定最佳连接策略,以防优化器无法找出真正最好采用的策略。
【讨论】:
以上是关于指定 HASH JOIN 比仅执行 JOIN 的优势?的主要内容,如果未能解决你的问题,请参考以下文章
谁能真正理解hash join/nested loop/merge join
多表连接的三种方式详解 HASH JOIN MERGE JOIN NESTED LOOP
Mysql 优化器内部JOIN算法hash join On-Disk Hash Join Grace Hash Join Hybrid hash join过程详解
Mysql 优化器内部JOIN算法hash join Nestloopjoin及classic hash join CHJ过程详解