我听说过关于并行选择查询的内存授予有冲突的事情:
- 内存授权乘以DOP
- 内存授权除以DOP
哪有
我听说过关于并行选择查询的内存授予有冲突的事情:
哪有
Answers:
对于需要额外内存的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);
如果运行此查询(同样,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);
有两种排序,现在是一个哈希联接。内存授权增加了一点,以适应散列构建,但不会增加一倍,因为Sort运算符不能同时运行。
如果更改查询以强制执行嵌套循环联接,则授予将加倍以处理并发的Sorts。
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);
内存授予量增加了一倍,因为嵌套循环不是阻塞运算符,而哈希联接是。
该查询选择不同组合的字符串数据。根据我选择的列,内存授予的大小将增加。
可变字符串数据的数据大小计算方式是行*列的声明长度的50%。对于VARCHAR和NVARCHAR,这是正确的,尽管NVARCHAR列由于存储了双字节字符而被加倍了。在某些情况下,使用新的CE确实会改变,但未记录详细信息。
数据的大小对于散列操作也很重要,但与对Sorts的程度不同。
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);
如果我在不同的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 ?);
对于每个交换运算符,要稍微增加一些处理并行缓冲区的数量,也许是出于内部原因,排序和哈希构建需要额外的内存来处理更高的DOP,但这显然不是乘数。