インデックス列は、テーブルにある列である必要はなく、テーブルの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コマンドの構文は通常、インデックス式を括弧で括る必要があります。 最初の例のように、式が単なる関数呼び出しの場合には括弧を省略することができます。
派生した式が、行が挿入、更新される度に実行されなければなりませんので、インデックス式は相対的に見て維持が高価です。 したがって、これらは、このインデックスを使用する問い合わせが非常に頻発に行なわれる時にのみ使用すべきです。