首先,来自 BOL :



这似乎足够清楚了。读取表变量而不修改它们的查询仍然可以并行化。

但后来在 SQL Server Storage Engine ,一个其他有信誉的来源,Sunil Agarwal 在 2008 年 3 月 30 日的一篇关于 tempdb 的文章中说:



Sunil 是在对 BOL 进行释义:INSERT,还是在 FROM 子句中存在表变量会阻止并行性?如果是这样,为什么?

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

谢谢!

最佳答案

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

我已将其匿名并:

  • BigParallelTable 是 900k 行和宽
  • 由于遗留原因,BigParallelTable 部分非规范化(我会修复它,稍后, promise )
  • 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]))
    

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

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

    关于sql - 读取表变量的查询能否在 SQL Server 2008 中生成并行执行计划?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1645846/

    10-12 07:33
    查看更多