5

First, from BOL:

Queries that modify table variables do not generate parallel query execution plans. Performance can be affected when very large table variables, or table variables in complex queries, are modified. In these situations, consider using temporary tables instead. For more information, see CREATE TABLE (Transact-SQL). Queries that read table variables without modifying them can still be parallelized.

That seems clear enough. Queries that read table variables, without modifying them, can still be parallelized.

But then over at SQL Server Storage Engine, an otherwise reputable source, Sunil Agarwal said this in an article on tempdb from March 30, 2008:

Queries involving table variables don't generate parallel plans.

Was Sunil paraphrasing BOL re: INSERT, or does the presence of table variables in the FROM clause prevent parallelism? If so, why?

I am thinking specifically of the control table use case, where you have a small control table being joined to a larger table, to map values, act as a filter, or both.

Thanks!

4

4 に答える 4

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)  

プラン

于 2011-11-23T13:17:49.730 に答える
5

OK、並列選択がありますが、テーブル変数ではありません

私はそれを匿名化しました:

  • 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」の1行と見なされます。

テーブル変数が並列で使用されていないことを宣言できますが、それを含むプランは他の場所で並列処理を使用できますか? したがって、BOL は正しく、SQL ストレージの記事は間違っています。

于 2009-10-30T07:58:29.523 に答える
2

[ここで自分の質問に答えて、関連する引用を適切に提示できるようにします....]

ボリス B、MSDN SQL Server フォーラムのスレッドから:

テーブル変数を使用する読み取り専用クエリは、引き続き並列化できます。変更されたテーブル変数を含むクエリは、連続して実行されます。Books Online の記述を修正します。(従業員追加)

と:

並列処理のサポートには 2 つのフレーバーがあることに注意してください。

A. オペレーターは並列スレッドにできる/できない

B. この演算子はツリーに存在するため、クエリを並列に実行できる/実行できない。

B は A のスーパーセットです。

私が知る限り、テーブル変数はBではなく、 Aである可能性があります。

別の関連する引用、re: インライン化されていない T-SQL TVF:

インライン化されていない T-SQL TVF... は、TVF 入力がランタイム定数 (変数やパラメーターなど) である場合、並列処理と見なされます。入力が (クロス適用からの) 列である場合、ステートメント全体で並列処理が無効になります。

于 2009-10-30T15:41:15.610 に答える
1

私の理解では、並列処理は UPDATE/DELETE/INSERT 操作のテーブル変数ではブロックされていますが、SELECT ではブロックされていません。もちろん、それを証明することは、仮説を立てるよりもはるかに困難です。:-)

于 2009-10-29T20:58:11.380 に答える