by Hayato Matsuura.

実行計画の処理


この節では、MicrosoftのSQL Serverにおける 最も良く現われる実行計画の処理を説明します。Microsoftの ドキュメントも参照して下さい。

インデックスとテーブルへのアクセス

SQL Serverの用語はシンプルになっています。 「Scan」はインデックス全体を読み込み、「Seek」はインデックスあるいはテーブルの指定された一部のみにアクセスするためにBツリーや 物理アドレス(RID、 Oracleで言うROWID)を使う処理になっています。

Index Seek, Clustered Index Seek

Index Seekは、Bツリーの走査に 加えて、一致するエントリを探すのにリーフノードチェーンをたどります。第1章, 「 SQLインデックスの内部構造も参照して下さい。

Index Scan, Clustered Index Scan

インデックスの全体つまり全行を、インデックスの順番に沿って読みます。様々なシステム統計情報に基づき、 インデックスの順序に沿って全行が必要と判断した時、データベースはこの処理を実行します。例えば、対応するorder by句がある時などです。

Key Lookup (Clustered)

クラスタ化インデックスから 1行を取り出します。これは、Oracleの索引構成表に対するINDEX UNIQUE SCANと同じです。データのクラスタリングも参照して下さい。

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のような、 パイプライン化されていない処理を途中で中断する動作の時は、非常に非効率になります。

著者について

Markus Winandの写真

Markus Winand氏は、開発者がSQLパフォーマンスを改善するお手伝いをしています。彼は、SQL Performance Explainedの 著者でもあり、出張トレーニングhttp://winand.at/での リモート講義も 行っています。

彼の本

カバー『SQLパフォーマンス詳解』

核心をわかりやすく 解説。

Markusから購入します
(送料無料+PDF)

Amazonで購入
(印刷版のみ)

“Use The Index, Luke!” by Markus Winand is licensed under a Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 Unported License.
法律上の通知 | 接触 | 無保証 | 商標 | Privacy | CC-BY-NC-ND 3.0 license