代码之家  ›  专栏  ›  技术社区  ›  Peter Radocchia

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

  •  4
  • Peter Radocchia  · 技术社区  · 15 年前

    首先,从 BOL :

    修改的查询 桌子 变量不会生成并行查询执行计划。当非常大时,性能会受到影响 桌子 变量或复杂查询中的表变量将被修改。在这些情况下,考虑改用临时表。有关详细信息,请参阅创建表(Transact-SQL)。已阅读的查询 桌子 不修改变量的变量仍然可以并行化。

    这似乎足够清楚了。查询 阅读 在不修改表变量的情况下,表变量仍然可以并行化。

    但后来在 SQL Server Storage Engine Sunil Agarwal是一位知名人士,他在2008年3月30日发表的一篇关于tempdb的文章中说:

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

    sunil是否改写了bol re:insert,或者from子句中的表变量是否阻止了并行性?如果是,为什么?

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

    谢谢!

    4 回复  |  直到 13 年前
        1
  •  5
  •   gbn    15 年前

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

    我已经匿名了,而且:

    • 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]))
    

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

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

        2
  •  4
  •   Martin Smith    13 年前

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

    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)  
    

    Plan

        3
  •  0
  •   Aaron Bertrand    15 年前

    我的理解是,对于更新/删除/插入操作,表变量的并行性是被阻塞的,而对于选择则不是。当然,要证明这一点要比假设困难得多。-)

        4
  •  0
  •   Peter Radocchia    15 年前

    [在这里回答我自己的问题,这样我就可以适当地提供相关的报价…]

    鲍里斯B,来自 thread 在msdn-sql-server论坛上:

    使用表变量的只读查询仍然可以并行化。涉及被修改的表变量的查询连续运行。 我们将在网上更正这些声明。 (电磁脉冲)。新增)

    还有:

    注意,有两种并行支持方式:

    a.操作员可以/不能在平行螺纹中

    b.查询不能/不能并行运行,因为树中存在该运算符。

    B是A的超集。

    据我所知,表变量是 B和 可能是 a.

    另一个相关引用,Re:非内联t-sql tvfs:

    如果TVF输入是运行时常量(例如变量和参数),则考虑使用非内联T-SQL TVF…进行并行处理。如果输入是列(来自交叉应用),那么整个语句的并行性将被禁用。