【问题标题】:Does HashMatch join use temp tables for both datasets in SQL Server?HashMatch 连接是否对 SQL Server 中的两个数据集都使用临时表?
【发布时间】:2018-06-23 13:18:10
【问题描述】:

我正在 AdventureWorks2014 DB 中执行以下查询。

SET STATISTICS IO ON

SELECT 
    e.JobTitle,
    a.City,
    p.LastName + ', ' + p.FirstName AS EmployeeName
FROM 
    HumanResources.Employee AS e
JOIN 
    Person.BusinessEntityAddress AS bea ON e.BusinessEntityID = bea.BusinessEntityID
JOIN 
    Person.Address a ON bea.AddressID = a.AddressID
JOIN 
    Person.Person AS p ON e.BusinessEntityID = p.BusinessEntityID ;

SET STATISTICS IO OFF

它生成一个执行计划,其中包含嵌套连接输出的哈希匹配(内部连接)(例如输出 1,290 行)和地址表索引扫描的输出(例如输出 2,19614 行)。

当发生哈希匹配(内连接)时,它是为输出 1 和输出 2 创建临时表 (#tables) 还是只为输出 1 创建临时表 (#tables)?

如果答案只是“输出 1”,那么为什么不为较小的输出创建“内存中”数据结构,而不是创建需要文件存储的物理表?

【问题讨论】:

  • 它通过从构建输入计算每一行的哈希值来创建一个哈希表。它为此操作请求内存授权。如果该值估计正确并获得所需的内存,它将执行所有“内存中”操作。如果它得到的内存比它需要的少,它会使用 tempdb。
  • @DenisRubashkin - 我的理解是它肯定会在 tempdb 中创建临时(哈希)表,问题是它是否对两个输出都执行此操作,还是仅对其中一个输出执行此操作?如果其中之一(较小的那个),为什么不能“在内存中”呢?为什么即使在没有负载的情况下 sql server 也不授予内存(就像我在没有负载的情况下运行一样)?
  • 它可能......它可能不会。它尽其所能。哈希和内存使用的概念是不相关的东西。 为什么即使在没有负载的情况下 sql server 也不授予内存 我不知道。你认为不是吗?
  • @Gsab,哈希表肯定不在 tempdb 中。仅当返回的行数多于 Denis 所说的估计行数时,它才会溢出到 tempdb。溢出记录在默认跟踪中。

标签: sql-server


【解决方案1】:

早安,

当发生哈希匹配(内连接)时,它是为输出 1 和输出 2 创建临时表 (#tables) 还是只为输出 1 创建临时表 (#tables)?

(*简而言之) SQL Server 使用统计信息来选择两个输入中较小的表,并将为该表创建哈希表。这就是为什么我们称这个表为“构建输入”。这是执行计划中最重要的一项。 SQL Server 尝试首先在内存中创建表,但如果没有位置,它将使用 TEMPDB 中的物理磁盘空间。

下一个 SQL Server 从更大的表(名为“probe input”)中获取数据,使用哈希匹配函数将其与哈希表进行比较,并返回任何匹配的行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-17
    • 2013-07-09
    • 1970-01-01
    • 1970-01-01
    • 2013-12-10
    • 2020-06-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多