実行計画の処理


実行計画の処理について、個人的に一番助かっているのは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章, 「データのクラスタリング: インデックスの強力さの2つ目も参照して下さい。

TABLE ACCESS BY INDEX ROWID

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

TABLE ACCESS FULL

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

このウェブサイトにぴったりのカップは僕たちのショップにあります。
#見た目もいい感じだし、ここでの僕の仕事を支えてくれています

結合

通常、結合処理で同時に処理できるのは 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

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

WINDOW NOSORT STOPKEY

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

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