インデックス列は、テーブルにある列である必要はなく、テーブルの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'と理解しますので、この検索速度は他の単純なインデックス問い合わせと同じです。 したがって、式に対するインデックスは取り出し速度が挿入、更新速度より重要な場合にのみ有用です。