可视化并处理哈希匹配联接

这篇文章是连接运算符系列的第三部分(请务必阅读第1部分-嵌套循环joins第2部分-merge joins )。 本文的翻译是专门为“ MS SQL Server Developer”课程的学生准备的。



哈希匹配联接是物理连接操作员的可靠工具。
如果如果无法容纳太多数据,则嵌套循环联接将失败,并且合并联接将要求对输入进行排序,而哈希匹配将连接您提交的所有数据(前提是对连接执行一个相等谓词,到目前为止,您的tempdb中有足够的可用空间。



观看YouTube相关视频


哈希匹配算法包括两个阶段,其工作方式如下:



在第一个构建阶段,SQL Server从一个输入表(通常是两个中的最小表)在内存中创建一个哈希表。 基于输入键计算哈希,然后将其与该行一起存储在哈希表的相应块中。 在大多数情况下,每个块中只有一行数据,但以下情况除外:


  1. 有重复键的行。
  2. 哈希函数会产生冲突,并且完全不同的键会接收相同的哈希(这种情况很少见,但有可能)。

创建哈希表后,“探测”(验证)阶段开始。 在第二步中,SQL Server为第二个输入表中的每一行计算键哈希,并检查在第一步中创建的哈希表中是否存在键哈希。 如果此哈希匹配,则检查哈希表中的行的键与第二个表中的行的键是否真正匹配(由于可能的冲突,必须执行此检查)。
当在构造阶段无法创建可以完全存储在内存中的哈希表时,就会出现哈希匹配算法的通用版本:



当内存中存储的数据过多时,或者SQL Server为哈希匹配连接提供的内存不足时,就会发生这种情况。


当SQL Server在构建阶段没有足够的内存来存储哈希表时,它将继续工作,将某些块存储在内存中,并将其他块放置在tempdb中。
在验证阶段,SQL Server将第二个表中的数据行连接到内存中构建阶段的块中。 如果当前可能与该行对应的块内存不足,则SQL Server将此行写入tempdb以供以后比较。


完成一个块的匹配后,SQL Server将从内存中清除此数据,并将以下块加载到内存中。 然后,它将第二个表的行(当前位于tempdb中)与内存中的新块进行比较。


与本系列中的每个物理连接语句一样,可以在Hugo Kornelis关于哈希匹配的帮助中找到有关哈希匹配语句的详细信息。


哈希匹配联接显示什么?


了解哈希匹配联接如何工作的内部特征,使我们能够确定优化器对数据和上游连接运算符的看法,从而帮助我们专注于性能调整。


下次您看到执行计划中使用了哈希匹配联接时,可以考虑以下几种情况:


  • 尽管哈希匹配联接可以合并庞大的数据集,但是从第一个输入表构造哈希表是一项阻止执行后续语句的阻塞操作。 在这方面,我总是检查是否有一种简单的方法可以将哈希匹配转换为嵌套循环或合并联接。 有时这是不可能的(嵌套循环的行太多或合并联接的未排序数据太多),但始终值得检查是否通过将统计信息更新为SQL Server选择非阻塞哈希匹配联接语句这一事实而导致了简单的索引更改或改进的估计值
  • 哈希匹配联接非常适合大型连接,因为它们可以传输到tempdb,这使它们可以建立与大型数据集的连接,这可能导致使用嵌套循环或合并联接语句的内存连接失败。
    • 如果看到哈希匹配联接语句,则表示SQL Server认为输入太大。 如果我们知道我们的输入数据不应太大,则值得检查统计信息或估计是否存在问题,因为SQL Server错误地选择了哈希匹配联接。
  • 当在内存中执行时, 哈希匹配联接非常有效。 当构建阶段进入tempdb时会出现问题。
    • 如果我注意到一个黄色的小三角形,表明连接到tempdb,则说明发生这种情况的原因:如果数据多于可用内存,则几乎无能为力,但是如果分配的内存看起来过小,则可能意味着统计信息可能还会导致一个问题,导致对SQL Server优化器的估算值过低。

感谢您阅读本文。 您可能还喜欢我的Twitter


我们在上一个公开课中介绍了该主题。 等待您的评论!

Source: https://habr.com/ru/post/zh-CN459314/


All Articles