【发布时间】: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