次のようなテーブルを考えてみましょう。
CREATE TABLE test1 ( id integer, content varchar );
アプリケーションはこの形式の多くの問い合わせを発行します。
SELECT content FROM test1 WHERE id = constant
;
事前に準備を行っていなければ、システムで一致する項目を全て検出するためには、test1
テーブル全体を1行ごとにスキャンする必要があります。
test1
に数多くの行があり、その問い合わせで返されるのが数行(おそらく0行か1行)しかない場合、これは明らかに効率が悪い方法と言えます。
システムがインデックスをid
列上で維持するように指示されていれば、一致する行を検出するのにより効率の良い方法を使うことができます。
例えば、検索ツリーを数層分検索するだけで済む可能性もあります。
ほとんどのノンフィクションの本で、同じような手法が使われています。 読者が頻繁に調べる用語および概念は、その本の最後にアルファベット順に索引としてまとめられています。 その本に興味を持った読者は、索引(インデックス)を調べ、比較的速く簡単に該当するページを開くことができるため、見たい場所を探すために本全部を読む必要はありません。 読者がよく調べそうな項目を予想するのが著者の仕事であるように、どのインデックスが実用的であるかを予測するのはデータベースプログラマの仕事です。
上述のようにid
列にインデックスを作成する場合は、以下のようなコマンドが使用できます。
CREATE INDEX test1_id_index ON test1 (id);
test1_id_index
というインデックス名には、何を選んでも構いませんが、そのインデックスを何のために作成したかを後で思い出せるような名前を選ぶべきです。
インデックスを削除するには、DROP INDEX
コマンドを使用します。
テーブルのインデックスは、いつでも追加および削除できます。
いったんインデックスを作成すれば、それ以上の処理は必要はありません。
システムは、テーブルが変更される時インデックスを更新し、シーケンシャルスキャンよりもインデックススキャンを行うことがより効率的と判断した場合、問い合わせでインデックスを使用します。
しかし、問い合わせプランナで情報に基づいた判断をするためには、定期的にANALYZE
コマンドを実行し、統計情報を更新する必要があるかもしれません。
インデックスが使われているかどうか、およびプランナがインデックスを使わないと判断した状況および理由を調べる方法については、14章性能に関するヒントを参照してください。
インデックスは、UPDATE
やDELETE
コマンドの検索条件でも使用できます。
さらに、インデックスは結合問い合わせでも使用されます。
したがって、結合条件で記述されている列にインデックスを定義すれば、結合を伴った問い合わせにかかる時間もかなり短縮できます。
大規模テーブルに対するインデックス作成が長時間にわたる可能性があります。
デフォルトでPostgreSQLはインデックス作成と並行してテーブルを読み取る(SELECT
文)ことができますが、書き込み(INSERT
、UPDATE
、DELETE
)はインデックス作成が終わるまでブロックされます。
これは多くの運用環境では受け入れられません。
インデックス作成中でも並行して書き込みできるようにすることができますが、いくつか注意しなければならないことがあります。
インデックスの同時作成の情報を参照してください。
インデックスが作成された後、システムでは、テーブルとインデックスとの間で常に同期を取っておく必要があります。 これにより、データ操作の処理にオーバーヘッドが加わります。 したがって、めったに使用されないインデックスや、まったく使用されなくなったインデックスは、削除しておいた方が良いでしょう。