在SQL Server中,并行性如何更改内存授予?


Answers:


10

对于需要额外内存的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,但这显然不是乘数。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.