インデックス列は、基礎をなすテーブルにある列である必要はなく、そのテーブルの1つ以上の列から計算される関数やスカラ式とすることもできます。 この機能は、ある演算結果に基づいた高速テーブルアクセスを行う時に有用です。
例えば、大文字小文字を区別せずに比較するための一般的な方法である、lower
関数での使用例を以下に示します。
SELECT * FROM test1 WHERE lower(col1) = 'value';
lower(column)
関数の結果にインデックスが定義されていれば、この問い合わせでインデックスを使用することができます。
CREATE INDEX test1_lower_col1_idx ON test1 (lower(col1));
このインデックスをUNIQUE
と宣言したとすると、col1
の値が同一となる行だけでなく、col1
の大文字小文字だけが違う行の生成を防ぐことになります。
したがって、式に対するインデックスを使用して、単なる一意性制約では定義できないような制約を強制することができます。
別の例として、以下のような問い合わせが頻繁に行われる場合を考えます。
SELECT * FROM people WHERE (first_name || ' ' || last_name) = 'John Smith';
この場合、以下のようなインデックスを作成する価値があるでしょう。
CREATE INDEX people_names ON people ((first_name || ' ' || last_name));
2番目の例に示すようにCREATE INDEX
コマンドの構文は通常、インデックス式を括弧で括る必要があります。
最初の例のように、式が単なる関数呼び出しの場合には括弧を省略することができます。
派生した式が、行が挿入、更新される度に実行されなければなりませんので、インデックス式は相対的に見て維持が高価です。
しかし、インデックス式はインデックス内にすでに格納されているため、インデックスを使用する検索の間は再計算されません。
上の両方の例では、システムは問い合わせを単なるWHERE indexedcolumn = 'constant'
と理解しますので、この検索速度は他の単純なインデックス問い合わせと同じです。
したがって、式に対するインデックスは取り出し速度が挿入、更新速度より重要な場合に有用です。