A resposta depende de muitos fatores, como versão, codificação e localidade do Postgres -
LC_COLLATE
em particular. A expressão nua
lower(description) LIKE '%abc%'
normalmente é um pouco mais rápido que description ILIKE '%abc%'
, e qualquer um é um pouco mais rápido que a expressão regular equivalente:description ~* 'abc'
. Isso é importante para varreduras sequenciais em que a expressão deve ser avaliada para cada linha testada. Mas para tabelas grandes como você demonstra em sua resposta, certamente usaria um índice. Para padrões arbitrários (não apenas ancorados à esquerda), sugiro um índice de trigramas usando o módulo adicional
pg_trgm
. Então falamos sobre milissegundos em vez de segundos e a diferença entre as expressões acima é anulada. Índices GIN e GiST (usando o
gin_trgm_ops
ou gist_trgm_ops
classes de operadores) suportam LIKE
(~~
), ILIKE
(~~*
), ~
, ~*
(e mais algumas variantes) iguais. Com um índice GIN trigrama na description
(normalmente maior que GiST, mas mais rápido para leituras), sua consulta usaria description ILIKE 'case_insensitive_pattern'
. Relacionado:
- Variações de desempenho de consulta PostgreSQL LIKE
- Strings UTF-8 semelhantes para campo de preenchimento automático
Noções básicas para correspondência de padrões no Postgres:
- Correspondência de padrões com LIKE, SIMILAR TO ou expressões regulares no PostgreSQL
Ao trabalhar com o referido índice trigrama é normalmente mais prático para trabalhar:
description ILIKE '%abc%'
Ou com o operador regexp que não diferencia maiúsculas de minúsculas (sem
%
curingas):description ~* 'abc'
Um índice em
(description)
não suporta consultas em lower(description)
Como:lower(description) LIKE '%abc%'
E vice versa.
Com predicados em
lower(description)
exclusivamente , o índice de expressão é a opção um pouco melhor. Em todos os outros casos, um índice em
(description)
é preferível, pois suporta ambos predicados que diferenciam maiúsculas de minúsculas e não diferenciam maiúsculas de minúsculas.