FTS no admite LIKE
La respuesta previamente aceptada era incorrecta. La búsqueda de texto completo con sus índices de texto completo no es para el LIKE
operador en absoluto, tiene sus propios operadores y no funciona para cadenas arbitrarias. Funciona con palabras basadas en diccionarios y derivaciones. Se hace de soporte emparejamiento de prefijo para las palabras , pero no con el LIKE
operador:
Índices de trigram para LIKE
Instalar el módulo adicional pg_trgm
que proporciona clases de operador de ginebra y de trigramas GiST índices para apoyar todas LIKE
y ILIKE
patrones , no sólo los de la izquierda anclados:
Índice de ejemplo:
CREATE INDEX tbl_col_gin_trgm_idx ON tbl USING gin (col gin_trgm_ops);
O:
CREATE INDEX tbl_col_gist_trgm_idx ON tbl USING gist (col gist_trgm_ops);
Consulta de ejemplo:
SELECT * FROM tbl WHERE col LIKE '%foo%'; -- leading wildcard
SELECT * FROM tbl WHERE col ILIKE '%foo%'; -- works case insensitively as well
Trigramas? ¿Qué pasa con las cuerdas más cortas?
Las palabras con menos de 3 letras en valores indexados aún funcionan. El manual:
Se considera que cada palabra tiene dos espacios como prefijo y un espacio como sufijo al determinar el conjunto de trigramas contenidos en la cadena.
¿Y patrones de búsqueda con menos de 3 letras? El manual:
Tanto LIKE
para búsquedas como para búsquedas de expresiones regulares, tenga en cuenta que un patrón sin trigramas extraíbles degenerará en un escaneo de índice completo.
Es decir, que los escaneos de índice / mapa de bits aún funcionan (los planes de consulta para la declaración preparada no se romperán), simplemente no le dará un mejor rendimiento. Por lo general, no hay una gran pérdida, ya que las cadenas de 1 o 2 letras apenas son selectivas (más de un pequeño porcentaje de las coincidencias de la tabla subyacente) y el soporte de índices no mejoraría el rendimiento para empezar, porque un escaneo completo de la tabla es más rápido.
text_pattern_ops
para la coincidencia de prefijo
Solo para patrones anclados a la izquierda (sin comodines iniciales), obtiene el óptimo con una clase de operador adecuada para un índice btree: text_pattern_ops
ovarchar_pattern_ops
. Ambas características integradas de Postgres estándar, no se necesitan módulos adicionales. Rendimiento similar, pero índice mucho menor.
Índice de ejemplo:
CREATE INDEX tbl_col_text_pattern_ops_idx ON tbl(col text_pattern_ops);
Consulta de ejemplo:
SELECT * FROM tbl WHERE col LIKE 'foo%'; -- no leading wildcard
O , si debe ejecutar su base de datos con la configuración regional 'C' (de hecho, no configuración regional), entonces todo se ordena según el orden de bytes de todos modos y un índice btree simple con la clase de operador predeterminada hace el trabajo.
Más detalles, explicación, ejemplos y enlaces en estas respuestas relacionadas en dba.SE: