by Hayato Matsuura.

実行計画の処理


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

Seq Scan

Seq Scanは、ディスクに保存されている通り(TABLE ACCESS FULLのように)に関係(テーブル)をスキャンします。

Index Scan

Index ScanはBツリー走査を行い、 一致する全ての値を検索するのにリーフノードをたどり、対応するテーブル上のデータを取り出します。INDEX RANGE SCANに続いてTABLE ACCESS BY INDEX ROWIDを行うのに似ています。第1章, 「 SQLインデックスの内部構造も参照して下さい。

いわゆるインデックスフィルタ述語は、Index Scanの パフォーマンス問題を引き起こします。次の節でその問題の 識別方法を説明しています。

Index Only Scan (PostgreSQL 9.2以降)

Index Only ScanはBツリー走査を行い、一致する全ての値を検索するのにリーフノードをたどります。 結果を返すのに必要な列が全てインデックスに含まれているので、 テーブルアクセスは不要です(例外としてMVCCのvisibility informationがあります)。インデックスのみのスキャン: テーブルアクセスを 避けるも参照して下さい。

Bitmap Index Scan / Bitmap Heap Scan / Recheck Cond

Tom Lane氏のPostgreSQLの パフォーマンスに関するメーリングリストへの投稿が非常に分かりやすく簡潔です。

プレーンなIndex Scanは、一度に 1つのタプルへのポインタをインデックスから取り出し、テーブル内のそのタプルにすぐアクセスします。 ビットマップスキャンは、一度に全てのタプルへのポインタを インデックスから取り出し、インメモリな「ビットマップ」データ構造を 使ってソートし、物理的なタプル位置の順にテーブルのタプルにアクセスします。

Tom Lane

協力してください

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

結合処理

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

Nested Loops

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

Hash Join / Hash

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

Merge Join

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

ソートとグルーピング

Sort / Sort Key

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

GroupAggregate

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

HashAggregate

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

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

Limit

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

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

WindowAgg

窓関数の使用を表します。効率的なページネーションのための窓関数の使用も参照して下さい。

注意

PostgreSQLでは、窓関数の使用時には最初のN件のみを取得するクエリは パイプライン化して実行できません。

著者について

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