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

神谷 雅紀
Escalation Engineer

 

物理操作と論理操作

実行プランを構成する各リレーショナルオペレータ (RelOp) には、物理操作 (PhysicalOp) と論理操作 (LogicalOp) があります。これらは、それぞれ、物理オペレータ、論理オペレータとも呼ばれます。

※ ( ) 内の表記は、XML showplan での表記です。

論理操作は何をするかを表し、物理操作はどのように行うのかを表しています。例えば、内部結合を行う場合、論理操作は Inner Join になります。この内部結合を Nested Loop で行う場合は、物理操作は Nested Loop になります。これは、Nested Loop という方法を用いて、Inner Join を実現するということを表しています。

 

物理操作が実行可能な論理操作

各物理操作が実行可能な論理操作は決まっています。その代表的なものをいくつか紹介します。

尚、ここでは、論理操作によって動作が全く異なるということを示したいだけなので、オペレータの詳細については説明しません。オペレータの詳細やすべてのオペレータについて確認したい場合は、Books Online を参照して下さい。

Nested Loops

Nested Loops 物理操作は、inner join, left outer join, left semi join, left anti semi join 論理操作しか実行することはできません。right 系の join は実行することができません。Nested Loops の動きを考えると、これは、当然であることが理解できるかと思います。Nested Loops は、inner input (left input) から 1 行取得し、それと結合する行を outer input (right input) から入力して結合処理を行います。従って、結合の基準は、常に left の行になります。そのため、left が right に一致するか?または left は right に一致しないか?という結合しかできないのです。

Merge Join

Merge Join 物理操作は、Nested Loops とは異なり、inner join, left/right outer join, left/right semi join, left/right anti semi join 論理操作を行うことができ、かつ、union も行うことができます。Merge Join は、両方の入力が同じ役割であり、1 対 1 (1-to-1) 、1 対 多 (1-to-many)、多 対 多 (many-to-many) の入力を処理できます。

Table Spool/Index Spool

Table Spool や Index Spool 物理操作には、Eager Spool と Lazy Spool 論理操作があります。Eager Spool は、一度にすべてのデータをスプールします。つまり、Stop and Go オペレータです。一方、Lazy Spool は、スプールしている行が要求された場合は、自身がスプールしている行をもとに結果を返し、スプールしていない行が要求された場合のみ、子オペレータに行を要求し、取得した行をスプールしておきます。

Parallelism

並列クエリで使用される Parallelism 物理操作も多数の論理操作を行います。Gather Streams 論理操作は、複数のスレッドによって生成された複数の結果を入力とし、それら入力をひとつにまとめて、結果を単一の出力とします。反対に、Distribute Streams 論理操作は、ひとつの入力と複数の出力を持ちます。また、Repartition Stream 論理操作は、複数の入力と複数の出力を持ちます。

 

以上のとおり、同じ物理操作であっても、それが行う論理操作が異なれば、その動作は全く異なります。物理操作のみからクエリの動きを知ることはできません。クエリの動きを正確につかむためには、物理操作、論理操作の両方を確認することが必要です。