读取表变量的查询是否可以在SQL Server 2008中生成并行执行计划?

Pet*_*hia 4 sql sql-server parallel-processing table-variable sql-server-2008

首先,来自BOL:

修改变量的查询不会生成并行查询执行计划.当修改非常大的变量或复杂查询中的变量时,性能会受到影响.在这些情况下,请考虑使用临时表.有关更多信息,请参见CREATE TABLE(Transact-SQL).读取变量而不修改它们的查询仍然可以并行化.

这看起来很清楚.读取表变量而不修改它们的查询仍然可以并行化.

但是在Sun Server Agarwal在2008年3月30日的一篇关于tempdb的文章中说,这是一个声誉卓着的SQL Server存储引擎:

涉及表变量的查询不会生成并行计划.

Sunil是否解释了BOL:INSERT,或者FROM子句中是否存在表变量会阻止并行性?如果是这样,为什么?

我正在考虑控制表用例,其中有一个小控件表连接到一个更大的表,映射值,充当过滤器,或两者兼而有之.

谢谢!

gbn*_*gbn 5

好的,我有一个并行选择但不在表变量上

我已将其匿名化并:

  • BigParallelTable是900k行和宽
  • 由于遗留原因,BigParallelTable被部分非规范化(我将修复它,稍后,承诺)
  • BigParallelTable经常生成并行计划,因为它不理想并且"昂贵"
  • SQL Server 2005 x64,SP3,内置4035,16个内核

查询+计划:

DECLARE @FilterList TABLE (bar varchar(100) NOT NULL)

INSERT @FilterList (bar)
SELECT 'val1' UNION ALL 'val2' UNION ALL 'val3'

--snipped

SELECT
     *
FROM
    dbo.BigParallelTable BPT
    JOIN
    @FilterList FL ON BPT.Thing = FL.Bar

StmtText
  |--Parallelism(Gather Streams)
       |--Hash Match(Inner Join, HASH:([FL].[bar])=([BPT].[Thing]), RESIDUAL:(@FilterList.[bar] as [FL].[bar]=[MyDB].[dbo].[BigParallelTable].[Thing] as [BPT].[Thing]))
            |--Parallelism(Distribute Streams, Broadcast Partitioning)
            |    |--Table Scan(OBJECT:(@FilterList AS [FL]))
            |--Clustered Index Scan(OBJECT:([MyDB].[dbo].[BigParallelTable].[PK_BigParallelTable] AS [BPT]))
Run Code Online (Sandbox Code Playgroud)

现在,考虑一下,表变量几乎总是一个表扫描,没有统计数据,并假设一行"估计行数= 1","实际.. = 3".

我们可以声明表变量不是并行使用的,但是包含计划可以在其他地方使用并行吗?所以BOL是正确的,SQL存储文章是错误的


Mar*_*ith 5

显示表变量本身的并行运算符的简单示例。

DECLARE @T TABLE
(
X INT
)
INSERT INTO @T
SELECT TOP 10000 ROW_NUMBER() OVER (ORDER BY (SELECT 0))
FROM master..spt_values v1,master..spt_values v2;

WITH E8(N)
     AS (SELECT 1
         FROM   @T a,
                @T b),
     Nums(N)
     AS (SELECT TOP (1000000) ROW_NUMBER() OVER (ORDER BY (SELECT 0))
         FROM   E8)
SELECT COUNT(N)
FROM   Nums
OPTION (RECOMPILE)  
Run Code Online (Sandbox Code Playgroud)

计划