Me he encontrado con la búsqueda de texto completo en postgres en los últimos días, y estoy un poco confundido acerca de la indexación cuando busco en varias columnas.
Los documentos de postgres hablan sobre la creación de un ts_vector
índice en columnas concatenadas, así:
CREATE INDEX pgweb_idx ON pgweb
USING gin(to_tsvector('english', title || ' ' || body));
que puedo buscar así:
... WHERE
(to_tsvector('english', title||' '||body) @@ to_tsquery('english', 'foo'))
Sin embargo, si quisiera a veces buscar solo el título, a veces solo el cuerpo, y a veces ambos, necesitaría 3 índices separados. Y si agregué en una tercera columna, eso podría ser 6 índices, y así sucesivamente.
Una alternativa que no he visto en los documentos es simplemente indexar las dos columnas por separado, y luego usar una WHERE...OR
consulta normal :
... WHERE
(to_tsvector('english', title) @@ to_tsquery('english','foo'))
OR
(to_tsvector('english', body) @@ to_tsquery('english','foo'))
La comparación de los dos en ~ 1 millón de filas parece no tener básicamente ninguna diferencia en el rendimiento.
Entonces mi pregunta es:
¿Por qué querría concatenar índices como este, en lugar de simplemente indexar columnas individualmente? ¿Cuáles son las ventajas / desventajas de ambos?
Mi mejor conjetura es que si supiera de antemano que solo querría buscar ambas columnas (nunca una a la vez), solo necesitaría un índice por concatenación que use menos memoria.
fuente
title
enbody
y luego indexar eso daría mucho valor, aunque estoy abierto a la corrección. Probablemente me limitaría a indexarlos por separado. Además, si fue una locura única que de alguna manera requirió que se concatenara, entonces supongo que podría ejecutar la consulta ad-hoc.Respuestas:
No, no necesitas índices separados. Utiliza la función de pesas. Son solo una etiqueta con la que puede consultar. Puede tener hasta cuatro etiquetas para consultar (AD).
Es posible que desee concatenar tsvectors, de modo que pueda aplicarles pesos por separado y luego juntarlos:
fuente
En realidad, la alternativa sería usar where con OR , y no AND .
Si tiene un índice en tsvector (cuerpo + título) y está buscando en él, las palabras buscadas pueden estar en el título O en el cuerpo.
Además, cuando realice la prueba, asegúrese de tener un número razonable de filas en la tabla.
El caso más simple que debería mostrar una buena diferencia: encuentra dos palabras, una de las cuales es muy probable que esté en el título. y el otro, es muy probable que esté en el cuerpo. Pero asegúrese de que no haya muchas filas que coincidan con ambos criterios. Por ejemplo, puede tener el 30% de la palabra "depesz" en el cuerpo. También tienes ~ 30% de posibilidades de tener "mysql" en el título. Pero tener "depesz y mysql" en cualquiera de los campos de la misma fila es muy poco probable. Y luego verifique el rendimiento con dichos índices.
fuente