PostgreSQL Index Only Scan 奮闘記 その3

どうも。村上です。

今回で3回目のPostgreSQLです。

今はこんな感じです。

追記型アーキテクチャ
バキューム
Visibility Map  ← 前回ここまで
プラン演算子 ← 今回ここ
Index Only Scan

では「プラン演算子」いってみよう!!

プラン演算子???

プラン演算子ってあまり聞きなれないですけど、簡単に言うと「explain」したら出てくるアレです。

上の「Seq Scan」ってのがプラン演算子です。

データを探しに行くときに、いろいろな探し方があります。
上から順に探したり、データがありそうな場所を探したりなどです。
その「探し方」が「プラン演算子」というイメージです。

ではプラン演算子をいろいろと見ていきましょう。

Seq Scan

まずは「Seq Scan」から!!

Seq Scanは最も基本的なもので、単に表を最初から最後へとスキャンするプラン演算子です。

postgresql-techscore-blog3-1

Explainではこんな感じです。

全行スキャンするので、レコードの多いテーブルには不向きです。
そういう時は次に説明するIndex Scanが良いです。

Index Scan

まずはexplainの結果から

コストの部分を見るとSeq Scanとくらべて随分少ない値になっています。
なんか速そうですね。

      IndexはIndex情報をツリー上に格納しています。
      検索条件に合うインデックスがあれば、インデックスを探索します。
      対象のデータが見つかれば、該当の行にアクセスしてデータを返します。

postgresql-techscore-blog3-2

データ量が多い時はIndex Scanはかなり有効なのですが、少ない時はSeq Scanの方が速かったりします。
PostgreSQLのオプティマイザがそこら辺を考えて状況に応じてIndex Scanを使うかSeq Scanを使うかを判断します。

あと、Index Scanはデータ量が多い時に有効なのですが、それは参照の時です。
Insertでデータが挿入される場合は遅くなります。
IndexがあるテーブルにはIndex情報も更新する必要があるため、Insert処理が遅くなってしまいます。
とは言っても、1件のInsertぐらいではあまり変わりませんが、100万件Insertしようとするとかなりコストが変わります。

対象データの取込は以前に書いたのでそちらを見て下さい。
大量データ取込のいろいろ-postgresql編

Nested Loop

続いて結合系です。

まずはNested Loopからです。

      Nested Loopは単純な結合方式です。
      外側のテーブル一行ごとに内側のテーブルを走査します。
      外側のテーブルの件数が少なく、かつ、内側テーブルに結合キーのインデックスがある場合に有効です。

postgresql-techscore-blog3-3

図はインデックスがない場合の図です。
内側テーブルをSeq Scanするので遅いです。
テーブルのサイズが大きくなればコストは膨らみます ⇒ 計算量はO(N×M)

結合キーでIndexがある場合は、内側テーブルの検索時はIndex Scanとなり高速化ができます。

EXPLAINはこんな感じです。

Merge Join

次はMerge Joinです。

      Merge Joinは結合キーでソートし、マッチングしていきます。
      外側のテーブルは1回調べれば良く、走査回数が減ります。
      処理対象の行が多いケースに有効です。

postgresql-techscore-blog3-4

ソートさえ出来れば速いけど、ソートが遅いと余り有効ではないです。
Merge Joinも結合キーでインデックスを作成すれば、速くなります。
結論として、インデックス重要ということですね。

EXPLAINはこんな感じです。

Hash Join

続いてHash Joinです。

      Merge Joinは内側のテーブルのハッシュ表を作成します。
      外側のテーブルはハッシュ表と付きあわせて結合していきます。
      ハッシュ表はメモリに作るので、一度作ってしまえば高速で動作します。

postgresql-techscore-blog3-5

ハッシュはメモリに作られるので速いのですが、ハッシュ表のサイズがメモリサイズより大きくなればかなり遅くなってしまいます。

EXPLAINはこんな感じです。

プラン演算子の無効化

上記にある結合系のEXPLAINですが、すべて同じSQLです。
でも、異なる実行計画を使ってます。
なぜか!?

実はプラン演算子を無効にする魔法があります。
そうしないと、全部Hash Joinになってしまうので。。。

こうすれば、プラン演算子を制御できます。

システムの運用中にすることは推奨できませんが、この実行計画でいいの!?
って時に調べるにはいいですね。

まとめ

今回はプラン演算子についてでした。
もうお気づきとは思いますが、「Index Only Scan」はプラン演算子の1つです。

ということで次回はIndex Only Scanについてです。

追記型アーキテクチャ
バキューム
Visibility Map
プラン演算子 ← イマココ
Index Only Scan ← ツギココ

Comments are closed, but you can leave a trackback: Trackback URL.