次のようなテーブルを考えてみましょう。
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コマンドを実行し、統計情報を更新する必要があります。 インデックスが使われているかどうか、およびプランナがインデックスを使わないと判断した状況および理由を調べる方法については、第13章を参照してください。
インデックスにより、UPDATEやDELETEコマンドの検索条件でも使用できます。 インデックスは、結合問い合わせでより多く使用されます。 したがって、結合条件で記述されている列にインデックスを定義すれば、結合を伴った問い合わせにかかる時間をかなり短縮できます。
大規模テーブルに対するインデックス作成が長期にわたる可能性があります。 デフォルトでPostgreSQLはインデックス作成中でも並行してテーブルを読み取る(SELECT)ことができますが、書き込み(INSERT、UPDATE、DELETE)はインデックス作成が終わるまでブロックされます。 これは多くの運用環境では受け入れられません。 インデックス作成中でも並行して書き込みできるようにすることができますが、いくつか注意しなければならないことがあります。 インデックスの同時作成の情報を参照してください。
インデックスが作成された後、システムでは、テーブルとインデックスとの間で常に同期を取っておく必要があります。 これにより、データ操作の処理にオーバーヘッドが加わります。 したがって、めったに使用されないインデックスや、まったく使用されなくなったインデックスは、削除しておいた方が良いでしょう。