by Hayato Matsuura.

実行計画の処理


実行計画の処理について、個人的に一番助かっているのはJulian Dyke氏の一覧です。しかし、ここでは別の方法で説明していきます。

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

INDEX UNIQUE SCAN

INDEX UNIQUE SCANは、 Bツリーの走査のみを行います。データベースは、一意制約により 検索条件が1件にしか一致しない事が確実な場合に、これを使います。第1章, 「 SQLインデックスの内部構造も参照して下さい。

INDEX RANGE SCAN

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

フィルタ述語は、INDEX RANGE SCANの パフォーマンス上の問題の原因になる事があります。次の節で、 どのようにそれを見分けるかを説明します。

INDEX FULL SCAN

インデックスの全体つまり全行を、インデックスの順番に沿って読みます。様々なシステム統計情報に基づき、 インデックスの順序に沿って全行が必要と判断した時、データベースはこの処理を実行します。例えば、対応するorder by句がある時などです。なお オプティマイザは、INDEX FAST FULL SCANを代わりに使い、 追加でソート処理を行う事もあります。第6章, 「ソートとグルーピングも参照して下さい。

INDEX FAST FULL SCAN

インデックスの全体つまり全行を、ディスクに保存されている通りに 読みます。この処理は、必要な列が全てインデックス上にある場合にフルテーブルスキャンの代わりに実行されるのが一般的です。 TABLE ACCESS FULLと同じくINDEX FAST FULL SCANも、複数ブロックの読み取り処理に利点があります。第5章, 「データのクラスタリングも参照して下さい。

TABLE ACCESS BY INDEX ROWID

前段のインデックス検索で取得したROWIDを使って、 テーブルから行を取り出します。第1章, 「 SQLインデックスの内部構造も参照して下さい。

TABLE ACCESS FULL

フルテーブルスキャンとして知られる処理です。テーブル全体つまり全行・全列をディスクに保存されている通りに 読みます。複数ブロックの読み出し処理により、フルテーブルスキャンの 速度は大幅に改善されはしますが、最も重い処理の1つである事に 変わりありません。IO処理も多いですが、フルテーブルスキャンでは全てのテーブルの行の値をチェックしなければならないので、 かなりのCPU時間も消費します。フルテーブルスキャンも参照して下さい。

協力してください

この記事が気に入ったら、私の書いた本「SQLパフォーマンス詳解」や私によるトレーニングもきっと気にいるはず。

結合

通常、結合処理で同時に処理できるのは 2テーブルまでです。1つのクエリにそれ以上の結合対象のテーブルがある場合、まず2つのテーブルを結合し、それからその中間結果を次のテーブルと 結合するというように、順番に処理されます。結合の話をする場合には、 「テーブル」という言葉は「中間結果」の事を指す場合もあるのです。

NESTED LOOPS JOIN

片方のテーブルから結果を取り出し、その結果をもう1つの テーブルの各行に対して問い合わせて、2つのテーブルを結合します。入れ子ループも参照して下さい。

HASH JOIN

ハッシュ結合では、結合の片方から候補となるレコードをハッシュテーブルにロードし、それを結合のもう片方の各行と 突き合わせます。ハッシュ結合も参照して下さい。

MERGE JOIN

マージ結合は、並べ替えられた2つのリストをジッパーのように マージします。結合の両辺は事前にソートしておく必要があります。ソートマージも参照して下さい。

ソートとグルーピング

SORT ORDER BY

order by句に従って、結果をソートします。この処理は、中間結果(パイプライン化されていないもの)を マテリアライズするために、非常に多くのメモリを必要とします。インデックスを使ったorder byも参照して下さい。

SORT ORDER BY STOPKEY

order by句に従って、結果セットの一部をソートします。パイプライン化された実行ができない場合は、 最初のN件のみを選択するクエリとして実行します。最初のN行のみの選択も参照して下さい。

SORT GROUP BY

group by列の結果セットをソートし、 次のステップで並べ替えられた結果をまとめます。この処理は、中間結果(パイプライン化されていないもの)を マテリアライズするために、非常に多くのメモリを必要とします。インデックスを使ったgroup byも参照して下さい。

SORT GROUP BY NOSORT

group by句に従って、並べ替え済みの 結果セットをまとめます。この処理は中間結果をバッファせず、パイプライン化して実行します。インデックスを使ったgroup byも参照して下さい。

HASH GROUP BY

ハッシュテーブルを使って結果をグルーピングします。この処理は、中間結果(パイプライン化されていないもの)を マテリアライズするために、非常に多くのメモリを必要とします。 出力は、一定のルールに沿って並べられているわけではないものになります。インデックスを使ったgroup byも参照して下さい。

最初のN件のみを選択するクエリ

最初のN件のみを選択するクエリの効率は、内部で動作する処理の実行モードに依存します。SORT ORDER BYのような、パイプライン化されていない処理を途中で中断する動作の時は、非常に非効率になります。

COUNT STOPKEY

必要な行数が取り出せた時点で、内部的な処理を中断します。最初のN行のみの選択も参照して下さい。

WINDOW NOSORT STOPKEY

必要な行数が取り出せた時点で実行を中断するために、窓関数(over句)を使います。効率的なページネーションのための窓関数の使用も参照して下さい。

著者について

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