実行プランを読む - 基本編 (その 2)

 

神谷 雅紀
Escalation Engineer

 

実行プランを読む - 基本編 (その 1) では、制御フローとデータフローの話をしました。今回は、若干特殊な動きをするオペレータの話をしたいと思います。

 

Stop And Go オペレータ

実行プランを読む - 基本編 (その 1) の例のように、ほとんどのオペレータは、自分の Open が呼ばれたら、下位オペレータの Open を呼び出し、Fetch が呼ばれたら、下位オペレータの Fetch を呼び出します。しかし、Stop And Go オペレータと呼ばれるオペレータは、それとは異なる動きをします。

代表的な Stop And Go オペレータが Sort です。Sort は、ご存知のとおり、指定されている順番に行を並び替えるオペレータです。行を順番に並び替えた後でないと、最初の行を上位オペレータに返せません。そのため、Sort は、Open の間にそのほとんどの仕事をします。具体的には、以下のような動きをします。

Open

上位オペレータから Open が呼び出される。
下位オペレータの Open を呼び出す。
下位オペレータの Open 呼び出しが復帰する。
下位オペレータの Fetch を呼び出す。
下位オペレータの Fetch 呼び出しが復帰し、1 行が返される。
受け取った行をキャッシュする。
下位オペレータの Fetch を呼び出し、次の行を要求する。

下位オペレータから、もう返す行がないことが通知される。
下位オペレータの Close を呼び出す。
キャッシュしている行を指定されている順番に並び替える。
並び替えが終わると、上位オペレータに制御を返す。

Fetch

並び替え済みの行セット内の最初の行を上位オペレータに返す。

上位オペレータに、もう返す行がないことを通知する。

Close

上位オペレータから Close が呼び出される。
Close 処理を行い、制御を上位オペレータに戻す。

Open 呼び出しが完了した時点では、最初の行を返せる状態になっていなければなりませんが、Sort がその状態になるためには、下位オペレータから返される行をすべて受け取り、それらの行を指定されている順番に並び替えなければいけません。 そのため、Open 時に下位オペレータの Fetch を呼び出し、すべての行を取得します。

この Sort の動きを知らないと、CXPACKET 待ちは悪いことか?にはよく理解できない部分があったかと思います。

Stop and Go オペレータには、Sort の他に、Hash Match や Eager Spool 論理オペレーションを行う Table Spool などがあります。Eager Spool は、Sort と同様に、Open 時に下位オペレータのすべての行をキャッシュ (スプール) します。Fetch 時には、スプールしている行を返し、下位オペレータは呼び出しません。Hash Mach は、Open 時にビルド入力からの行をすべて読み取り、ハッシュテーブルを作ります。Fetch 時には、プローブ入力となるオペレータは呼び出しますが、ビルド入力となるオペレータは呼び出しません。

 

一回目を書き始めた時は、二回目では Stop And Go オペレータと Rebind/Rewind の話を書こうと思っていましたが、実行プランについては、ビューカウントを見る限り、皆さんあまり興味はないようですので、今回は、ここまでにしたいと思います。次に実行プランについて書く機会があれば、その時は、Rebind/Rewind や論理オペレータや物理オペレータ、コストなど、もう少し詳しい話をしたいと思います。