DOPは並列クエリで使用されるスレッド数ではない

神谷 雅紀
Escalation Engineer

並列クエリの並列度または次数 (degree of parallelism, DOP) は、クエリを実行するために使用される総スレッド数もしくは最大スレッド数ではありません。

例えば、Gather Streams Parallelism オペレータをひとつ含むクエリが DOP = 4 で実行されると、クエリで使用されるスレッドは、Parallelism オペレータよりも上を担当するメインスレッド 1 つと下を担当する子スレッド 4 つの合計 5 スレッドになります。

DOP とは?

DOP は、個々の Parallelism オペレータに作用し、クエリ内の各 Parallelism オペレータが子スレッドを作成する場合のスレッド数を規定します。max degree of parallelism や MAXDOP クエリヒントによって、この各 Parallelism オペレータが生成できる子スレッドの最大値を設定することが可能です。子スレッドが実際にいくつ生成されるかは、論理オペレータと指定されている DOP に加えて、その時点でのインスタンス内のスレッド使用状況に依存します。

並列クエリで使用される論理オペレータ

Parallelism オペレータでは、子スレッド (Producer) から親スレッド (Comsumer) へのデータの受け渡しが行われます。受け渡し方法は、論理オペレータによって異なります。DOP により制限されるのは子スレッド (Producer) です。

Gather Streams

複数の子スレッドからデータを受け取り、ひとつの親スレッドにデータを渡します。

gather

Distribute Streams

ひとつの子スレッドからデータを受け取り、複数の親スレッドにデータを渡します。

dist

Repartition Streams

複数の子スレッドからデータを受け取り、複数の親スレッドにデータを渡します。

repart

Parallelism オペレータが 2 つ以上ある場合には、上位の Parallelism の子スレッドは、下位の Parallelism の親スレッドになります。

スレッド間でのデータの受け渡し方法については、以下の以前のポストを参照して下さい。スレッド数についても、図をベースに説明しています。最初の図は DOP 4 でのクエリ実行を表していますが、そのクエリによって使用されるスレッド数は 13 です。

CXPACKET 待ちは悪いことか?

https://blogs.msdn.com/b/jpsql/archive/2011/08/30/cxpacket.aspx