Eri*_*ing 9 sql-server parallelism memory-grant
我听说过关于并行选择查询的内存授予的相互矛盾的事情:
是哪个?
Eri*_*ing 11
对于需要额外内存的 SQL Server 查询,会为串行计划派生授权。如果探索和选择并行计划,内存将在线程之间平均分配。
内存授予估计基于:
如果选择并行计划,则处理并行交换(分发、重新分发和收集流)会产生一些内存开销,但是它们的内存需求仍然不是以相同的方式计算的。
要求内存的最常见运算符是
需要内存的不太常见的运算符是插入到列存储索引。它们的不同还在于内存授予当前乘以它们的 DOP。
排序的内存需求通常比散列高得多。排序将要求至少估计的内存授予数据大小,因为它们需要按排序元素对所有结果列进行排序。哈希需要内存来构建哈希表,哈希表不包括所有选定的列。
如果我运行这个查询,故意暗示 DOP 1,它将要求 166 MB 的内存。
SELECT *
FROM
(
SELECT TOP (1000)
u.Id
FROM dbo.Users AS u
ORDER BY u.Reputation
) AS u
OPTION(MAXDOP 1);
Run Code Online (Sandbox Code Playgroud)
如果我运行这个查询(再次,DOP 1),计划将改变,并且内存授予将略微增加。
SELECT *
FROM (
SELECT TOP (1000)
u.Id
FROM dbo.Users AS u
ORDER BY u.Reputation
) AS u
JOIN (
SELECT TOP (1000)
u.Id
FROM dbo.Users AS u
ORDER BY u.Reputation
) AS u2
ON u.Id = u2.Id
OPTION(MAXDOP 1);
Run Code Online (Sandbox Code Playgroud)
有两种排序,现在是哈希联接。内存授予稍微增加以适应散列构建,但它不会加倍,因为 Sort 运算符不能同时运行。
如果我更改查询以强制嵌套循环连接,则授权将加倍以处理并发排序。
SELECT *
FROM (
SELECT TOP (1000)
u.Id
FROM dbo.Users AS u
ORDER BY u.Reputation
) AS u
INNER LOOP JOIN ( --Force the loop join
SELECT TOP (1000)
u.Id
FROM dbo.Users AS u
ORDER BY u.Reputation
) AS u2
ON u.Id = u2.Id
OPTION(MAXDOP 1);
Run Code Online (Sandbox Code Playgroud)
内存授予加倍,因为嵌套循环不是阻塞运算符,而 Hash Join 是。
此查询选择不同组合的字符串数据。根据我选择的列,内存授予的大小会增加。
为可变字符串数据计算数据大小的方式是行 * 列声明长度的 50%。对于 VARCHAR 和 NVARCHAR 也是如此,尽管 NVARCHAR 列被加倍,因为它们存储双字节字符。在某些情况下,这在新 CE 中确实会发生变化,但没有记录详细信息。
数据的大小对散列操作也很重要,但与排序的程度不同。
SELECT *
FROM
(
SELECT TOP (1000)
u.Id -- 166MB (INT)
, u.DisplayName -- 300MB (NVARCHAR 40)
, u.WebsiteUrl -- 900MB (NVARCHAR 200)
, u.Location -- 1.2GB (NVARCHAR 100)
, u.AboutMe -- 9GB (NVARCHAR MAX)
FROM dbo.Users AS u
ORDER BY u.Reputation
) AS u
OPTION(MAXDOP 1);
Run Code Online (Sandbox Code Playgroud)
如果我在不同的 DOP 上运行此查询,则内存授予不会乘以 DOP。
SELECT *
FROM (
SELECT TOP (1000)
u.Id
FROM dbo.Users AS u
ORDER BY u.Reputation
) AS u
INNER HASH JOIN (
SELECT TOP (1000)
u.Id
FROM dbo.Users AS u
ORDER BY u.Reputation
) AS u2
ON u.Id = u2.Id
ORDER BY u.Id, u2.Id -- Add an ORDER BY
OPTION(MAXDOP ?);
Run Code Online (Sandbox Code Playgroud)
每个交换操作符处理更多并行缓冲区的情况略有增加,也许存在内部原因,即 Sort 和 Hash 构建需要额外的内存来处理更高的 DOP,但这显然不是一个乘数。
归档时间: |
|
查看次数: |
287 次 |
最近记录: |