Chapter 8. インデックス

Table of Contents
8.1. 序文
8.2. インデックスの型
8.3. 複数列インデックス
8.4. 一意インデックス
8.5. 関数インデックス
8.6. 演算子クラス
8.7. 部分インデックス
8.8. インデックス使用状況の検証

インデックスは、データベースのパフォーマンスをを向上させるための一般的な方法です。 データベースサーバでインデックスを使用すると、インデックスを使用しない場合に比べてかなり速く、特定の行を検出し抽出することができます。 しかし、インデックスを使用すると、データベースシステム全体にオーバーヘッドを追加することにもなるため、注意して使用する必要があります。

8.1. 序文

インデックスが必要となる典型的な例は、次のようなテーブルがあって、

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 コマンドを実行し、統計情報を更新する必要があります。 また、インデックスが使われているかどうか、およびプランナがインデックスを使わないと判断した状況および理由を調べる方法については、Chapter 10 を参照してください。

インデックスにより、UPDATEDELETE コマンドでも検索条件を使用できます。 また、インデックスは、結合問い合わせでも使用可能です。 したがって、結合条件で記述されている列にインデックスを定義すれば、結合を伴った問い合わせにかかる時間をかなり短縮できます。

インデックスが作成された場合、システムでは、テーブルとインデックスとの間で常に同期を取っておく必要があります。 これにより、データ操作の処理にオーバーヘッドが加わります。 したがって、必要でないインデックスや、全く使用されないインデックスは、削除しておいた方がよいでしょう。 また、問い合わせやデータ操作のコマンドでは、1 つのテーブルに対して最大 1 つのインデックスのみ使用可能であることに注意して下さい。