インデックスの構築

インデックスは,巨大なデータベースに対して空間データベースを利用できるようにするためのものです.インデックスが無い場合,図形についての全ての検索はデータベース中の全てのレコードの"sequential scan"が必要となるでしょう.インデックスは,特定のレコードを見つけるためにすばやく探索できる検索ツリーにデータを組織化することにより,検索をスピードアップします.PostgreSQLは既定でB-Tree,R-Tree,GiSTの3種類のインデックスをサポートします

GiSTインデックス

GiSTは"Generalized Search Tree"の略語で,インデックスの汎用形式です.GISのインデクシングに加えて,通常のB-Treeインデックスにあてはめられない(not amenable)全ての種類の不規則なデータ構造(整数配列,空間データ等)の検索をスピードアップするために使われます.

ひとたびGISデータテーブルが数千行を上回れば,データの空間的な検索のスピードアップの為にインデックスを作りたくなるでしょう(すべての検索が属性ベースで無い限り.この場合,属性フィールドに通常のインデックスを作りたくなるでしょう).

"geometory"カラムのGiSTインデックスを構築するための構文は以下のようになります:

  CREATE INDEX [indexname] ON [tablename] 
    USING GIST ( [geometryfield] GIST_GEOMETRY_OPS ); 

空間インデックスの構築は計算的に激しい課題です:およそ100万行のテーブルを300MHzのSolarisマシンで,GiSTインデックスの構築に約1時間かかることが分かっています.インデックスを構築した後,PostgreSQLにクエリの計画を最適化するために使われるテーブルの統計値(statisticS)を集めさせることは重要です:

  VACUUM ANALYZE;

PostgreSQLにおいてGiSTインデックスはR-Treeインデックスより2つの利点があります.最初は,GiSTインデックスは"null safe"です.これは,null値を含むカラムのインデックスを作ることができることを意味します.2つ目は,GiSTインデックスはPostgreSQLの8Kのページサイズより大きなGISを扱うときに重要な"lossiness"の概念(concept)をサポートします.LossinessはPostgreSQLにオブジェクトの「重要な("important")部分だけをインデックスに格納することを許します--GISオブジェクトの場合,ちょうどbounding boxになります.8Kより大きなGISオブジェクトはR-Treeインデックスに構築プロセスでの失敗を引き起こすでしょう.

インデックスの利用

普通,インデックスは見えないところでデータアクセスをスピードアップする:一度インデックスが作られると,クエリプランナはユーザに意識させること無くクエリプランをスピードアップするためにインデックスの情報を使うタイミングを決定します.不幸にも,PostgreSQLのクエリプランナはGiSTインデックスの利用をあまり最適化していません.そのため時々,空間インデックスを使うべき検索が,既定のテーブル全体の逐次走査(sequence scan)となります.

もし,空間インデックスが(ついでに属性インデックスも含めて)使われていないことを発見したら,あなたが行える一組のことがあります: