この節では、MicrosoftのSQL Serverにおける 最も良く現われる実行計画の処理を説明します。Microsoftの ドキュメントも参照して下さい。
インデックスとテーブルへのアクセス
SQL Serverの用語はシンプルになっています。
        「Scan」はインデックス全体を読み込み、「Seek」はインデックスあるいはテーブルの指定された一部のみにアクセスするためにBツリーや
        物理アドレス(RID、
        Oracleで言うROWID)を使う処理になっています。
- Index Seek, Clustered Index Seek
- Index Seekは、Bツリーの走査に 加えて、一致するエントリを探すのにリーフノードチェーンをたどります。第1章1, 「 SQLインデックスの内部構造」も参照して下さい。
- Index Scan, Clustered Index Scan
- インデックスの全体つまり全行を、インデックスの順番に沿って読みます。様々なシステム統計情報に基づき、 インデックスの順序に沿って全行が必要と判断した時、データベースはこの処理を実行します。例えば、対応する - order by句がある時などです。
- Key Lookup (Clustered)
- クラスタ化インデックスから 1行を取り出します。これは、Oracleの索引構成表に対する - INDEX UNIQUE SCANと同じです。「データのクラスタリング: インデックスの強力さの2つ目」も参照して下さい。
- RID Lookup (Heap)
- テーブルから1行を取り出します。Oracleの - TABLE ACCESS BY INDEX ROWIDに当ります。「 SQLインデックスの内部構造」も参照して下さい。
- Table Scan
- フルテーブルスキャンとして知られる処理です。 テーブル全体つまり全行・全列をディスクに保存されている通りに読みます。複数ブロックの読み出し処理により、 - Table Scanの速度は大幅に改善されはしますが、最も重い処理の1つである事に 変わりありません。IO処理も多いですが、- Table Scanでは 全てのテーブルの行の値をチェックしなければならないので、かなりのCPU時間も消費します。「フルテーブルスキャン」も参照して下さい。
協力してください
この記事が気に入ったら、私の書いた本「SQLパフォーマンス詳解」や私によるトレーニングもきっと気にいるはず。
結合処理
通常、結合処理で同時に処理できるのは2テーブルまでです。1つのクエリにそれ以上の結合対象のテーブルがある場合、 まず2つのテーブルを結合し、それからその中間結果を次のテーブルと結合するというように、順番に処理されます。結合の話をする場合には、 「テーブル」という言葉は「中間結果」の事を指す場合もあるのです。
- Nested Loops
- 片方のテーブルから結果を取り出し、その結果をもう1つの テーブルの各行に対して問い合わせて、2つのテーブルを結合します。SQL Serverでは、インデックスアクセスの後にテーブルデータを取り出すのにも入れ子のループ処理を使います。「入れ子ループ」も参照して下さい。 
- Hash Match
- ハッシュマッチ結合では、 結合の片方から候補となるレコードをハッシュテーブルにロードし、それを結合のもう片方の各行と突き合わせます。「ハッシュ結合」も参照して下さい。 
- Merge Join
- マージ結合は、 並べ替えられた2つのリストをジッパーのようにマージします。結合の両辺は事前にソートしておく必要があります。「ソートマージ」も参照して下さい。 
ソートとグルーピング
- Sort
- order by句に従って、結果をソートします。この処理は、 中間結果(パイプライン化されていないもの)をマテリアライズするために、非常に多くのメモリを必要とします。「インデックスを使ったorder by」も参照して下さい。
- Sort (Top N Sort)
- order by句に従って、結果セットの一部をソートします。パイプライン化された実行ができない場合は、 最初のN件のみを選択するクエリとして実行します。「最初のN行のみの選択」も参照して下さい。
- Stream Aggregate
- group by句に従って、 並べ替え済みの結果セットをまとめます。この処理は中間結果をバッファせず、パイプライン化して実行します。「インデックスを使ったgroup by」も参照して下さい。
- Hash Match (Aggregate)
- レコードをグルーピングするのに一時的なハッシュテーブルを使います。 この処理では、データセットは事前にソートされている必要はありませんが、 中間結果(パイプライン化されていないもの)をマテリアライズするために非常に多くのメモリを必要とします。出力は、 一定のルールに沿って並べられているわけではないものになります。「インデックスを使ったgroup by」も参照して下さい。 
最初のN件のみを選択するクエリ
- Top
- 必要な行数が取り出せた時点で、内部的な処理を中断します。「最初のN行のみの選択」も参照して下さい。 - 最初のN件のみを選択するクエリの効率は、 内部で動作する処理の実行モードに依存します。 - Sortのような、 パイプライン化されていない処理を途中で中断する動作の時は、非常に非効率になります。

