É exatamente como você lê em jjanes em outro lugar:um índice de expressão só é considerado se a expressão corresponder exatamente ao predicado da consulta. O planejador de consultas do Postgres não é uma IA. Isso anularia rapidamente o propósito de tornar as consultas rápidas se o planejamento levar muito tempo.
Você pode otimizar um pouco seu índice, se isso servir de consolo.
left()
é mais simples e rápido que substring()
:CREATE INDEX record_changes_log_detail_old_value_ix_btree
ON record_changes_log_detail (left(old_value,1024) text_pattern_ops);
Além disso, há um tamanho máximo de linha de 2.704 bytes para índices btree, não um "limite de 2172 caracteres em árvores B" .
Mais importante, apenas para verificações de igualdade, como sua pergunta sugere, um índice btree em um valor de hash usando
md5(old_value)
ou hashtext(old_value)
seria muito mais eficiente. Se fizer isso, lembre-se de se defender contra colisões de hash igual a:SELECT *
FROM record_changes_log_detail
WHERE hashtext(old_value) = hashtext('Gold Kerrison Neuro')
AND old_value = 'Gold Kerrison Neuro';
O primeiro predicado oferece acesso rápido ao índice. O segundo exclui falsos positivos. As colisões devem ser extremamente raras. Mas possível. E a possibilidade cresce com o tamanho da mesa.
Relacionado:
- A consulta SELECT com DISTINCT em uma estrutura de tabela para gráficos é muito lenta
- Qual é o tipo de dados ideal para um campo MD5?
- Pesquisa de texto completo no CouchDB
Ou um índice de hash como você já está se considerando:
- Por que um índice de hash do Postgres 11 é tão grande?
(Aqui você não precisa se preocupar com colisões de hash; tratado internamente.)