FTS não suporta LIKE
A resposta aceita anteriormente estava incorreta. A pesquisa de texto completo com seus índices de texto completo não para o
LIKE
operador, ele tem seus próprios operadores e não funciona para strings arbitrárias. Ele opera em palavras baseado em dicionários e lematização. Ele faz suporta correspondência de prefixo para palavras , mas não com o LIKE
operador:- Obter correspondência parcial da coluna TSVECTOR indexada por GIN
Índices de trigramas para LIKE
Instale o módulo adicional
pg_trgm
que fornece classes de operadores para índices de trigramas GIN e GiST para suportar todos os LIKE
e ILIKE
padrões , não apenas os ancorados à esquerda:Índice de exemplo:
CREATE INDEX tbl_col_gin_trgm_idx ON tbl USING gin (col gin_trgm_ops);
Ou:
CREATE INDEX tbl_col_gist_trgm_idx ON tbl USING gist (col gist_trgm_ops);
- Diferença entre o índice GiST e GIN
Exemplo de consulta:
SELECT * FROM tbl WHERE col LIKE '%foo%'; -- leading wildcard
SELECT * FROM tbl WHERE col ILIKE '%foo%'; -- works case insensitively as well
Trigramas? E as cordas mais curtas?
Palavras com menos de 3 letras em valores indexados ainda funcionam. O manual:
Cada palavra é considerada como tendo dois espaços prefixados e um espaço prefixado ao determinar o conjunto de trigramas contidos na string.
E padrões de pesquisa com menos de 3 letras? O manual:
Para ambosLIKE
e pesquisas de expressão regular, lembre-se de que um padrão sem trigramas extraíveis degenerará em uma varredura de índice completo.
Ou seja, as verificações de índice / bitmap de índice ainda funcionam (os planos de consulta para a instrução preparada não serão interrompidos), apenas não comprarão melhor desempenho. Normalmente, nenhuma grande perda, já que strings de 1 ou 2 letras dificilmente são seletivas (mais do que alguns por cento das correspondências de tabela subjacentes) e o suporte a índice não melhoraria o desempenho para começar, porque uma varredura completa da tabela é mais rápida.
text_pattern_ops
para correspondência de prefixo
Apenas para ancorados à esquerda padrões (sem curinga inicial) você obtém o melhor com uma classe de operador adequada para um índice btree:
text_pattern_ops
ou varchar_pattern_ops
. Ambos os recursos internos do Postgres padrão, sem necessidade de módulo adicional. Desempenho semelhante, mas índice muito menor. Índice de exemplo:
CREATE INDEX tbl_col_text_pattern_ops_idx ON tbl(col text_pattern_ops);
Exemplo de consulta:
SELECT * FROM tbl WHERE col LIKE 'foo%'; -- no leading wildcard
Ou , se você deve executar seu banco de dados com o 'C' localidade (efetivamente não locale), então tudo é classificado de acordo com a ordem de bytes de qualquer maneira e um índice btree simples com classe de operador padrão faz o trabalho.
Mais detalhes, explicações, exemplos e links nestas respostas relacionadas no dba.SE:
- Correspondência de padrões com LIKE, SIMILAR TO ou expressões regulares no PostgreSQL
- Como o LIKE é implementado?
- Encontrando strings semelhantes com o PostgreSQL rapidamente