Uma coluna de índice não precisa ser apenas uma coluna da tabela subjacente, podendo ser uma função, ou expressão escalar calculada a partir de uma ou mais colunas da tabela. Este recurso é útil para obter acesso rápido a tabelas com base nos resultados de cálculos.
Por exemplo, uma maneira comum de fazer comparações que não
diferenciam letras maiúsculas de minúsculas é usando a função
lower:
SELECT * FROM test1 WHERE lower(col1) = 'valor';
Se tiver sido definido um índice no resultado da função
lower(col1), esta consulta poderá usá-lo:
CREATE INDEX test1_lower_col1_idx ON test1 (lower(col1));
Se este índice for declarado como UNIQUE, vai
impedir a criação de linhas cujos valores de col1
diferem apenas por letras maiúsculas e minúsculas, bem como linhas
cujos valores de col1 sejam realmente idênticos.
Portanto, índices de expressões podem ser usados para impor restrições
que não são definíveis como simples restrições de unicidade.
Como outro exemplo, se alguém costuma fazer consultas como:
SELECT * FROM pessoas WHERE (primeiro_nome || ' ' || último_nome) = 'John Smith';
então pode valer a pena criar um índice como este:
CREATE INDEX pessoas_nomes_idx ON pessoas ((primeiro_nome || ' ' || último_nome));
A sintaxe do comando CREATE INDEX normalmente
requer que se escreva parênteses em torno das expressões de índice,
conforme mostrado no segundo exemplo.
Os parênteses podem ser omitidos quando a expressão é apenas uma
chamada de função, como no primeiro exemplo.
As expressões de índice são relativamente caras de manter, porque
a(s) expressão(ões) derivada(s) deve(m) ser calculada(s) para cada
inserção e atualização não-HOT
(Heap-Only Tuples) de linha.
Entretanto, as expressões de índice não são
recalculadas durante a procura indexada, porque já estão armazenadas
no índice.
Nos dois exemplos acima, o sistema vê a consulta apenas como
WHERE coluna_indexada = 'constante', portanto
a velocidade da procura é equivalente a qualquer outra consulta de
índice simples.
Assim, índices de expressões são úteis quando a velocidade de
recuperação é mais importante do que a velocidade de inserção e
atualização.