2009-10-08 15 views
15

Estoy probando las funciones de búsqueda de texto de PostgreSQL, utilizando el volcado de datos de septiembre de StackOverflow como datos de muestra. :-)¿Por qué los índices GiST de Text-Search de PostgreSQL son mucho más lentos que los índices GIN?

El enfoque ingenuo de utilizar LIKE predicados o POSIX expresiones regulares para buscar 1,2 millones de filas tarda unos 90-105 segundos (en mi Macbook) para hacer una mesa de exploración completa la búsqueda de una palabra clave.

SELECT * FROM Posts WHERE body LIKE '%postgresql%'; 
SELECT * FROM Posts WHERE body ~ 'postgresql'; 

Un ad hoc consulta de búsqueda de texto no indexados tarda unos 8 minutos:

SELECT * FROM Posts WHERE to_tsvector(body) @@ to_tsquery('postgresql'); 

Creación de un índice GIN tarda unos 40 minutos:

ALTER TABLE Posts ADD COLUMN PostText TSVECTOR; 
UPDATE Posts SET PostText = to_tsvector(body); 
CREATE INDEX PostText_GIN ON Posts USING GIN(PostText); 

(I me doy cuenta de que también podría hacer esto en un paso definiéndolo como un índice de expresión.)

Posteriormente, una búsqueda asistida por un índice de GIN corre mucho más rápido - esto tarda unos 40 milisegundos :

SELECT * FROM Posts WHERE PostText @@ 'postgresql'; 

Sin embargo, cuando se crea un índice de Gist, los resultados son bastante diferentes. Se tarda menos de 2 minutos para crear el índice:

CREATE INDEX PostText_GIN ON Posts USING GIST(PostText); 

Posteriormente, una consulta usando el operador @@ de búsqueda de texto toma 90-100 segundos. Así que los índices GiST mejoran una consulta TS no indexada de 8 minutos a 1.5 minutos. Pero eso no mejora si se hace una exploración de tabla completa con LIKE. Es inútil en un entorno de programación web.

¿Me está faltando algo crucial para usar índices GiST? ¿Los índices deben estar almacenados previamente en la memoria o algo así? Estoy usando una instalación sencilla de PostgreSQL desde MacPorts, sin ajustes.

¿Cuál es la forma recomendada de usar índices GiST? ¿O todos los que hacen TS con PostgreSQL saltan los índices GiST y usan solo índices GIN?

PD: Sé sobre alternativas como Sphinx Search y Lucene. Solo intento conocer las características proporcionadas por PostgreSQL.

Respuesta

5

tratar

CREATE INDEX PostText_GIST ON Posts USING GIST(PostText varchar_pattern_ops); 

que crea un índice adecuado para las consultas de prefijo. Consulte los documentos de PostgreSQL en Operator Classes and Operator Families. El operador @@ solo es sensible en vectores de términos; el índice GiST (con varchar_pattern_ops) dará excelentes resultados con LIKE.

+0

Gracias por su respuesta, I' Voy a probar tu sugerencia ... –

+1

Debe haber llevado bastante tiempo generar ese índice. :) –

+5

Esto no puede funcionar porque 'varchar_pattern_ops' es para el tipo' varchar', y 'PostText' es del tipo' tsvector', y solo está definido para los índices 'btree' y' hash' y no para 'gist'. –

6

Los documentos tienen una buena descripción general de las diferencias de rendimiento entre los índices GiST y GIN si está interesado: GiST and GIN Index Types.

2

por cierto: si esto no se ha contestado a su satisfacción, sin embargo, la parte en la que hizo

SELECT * FROM Posts WHERE PostText @@ 'postgresql';

debería haber sido

SELECT * FROM Posts WHERE PostText @@ to_tsquery('postgresql');

+0

Gracias por el consejo, lo intentaré la próxima vez que pruebo PostgreSQL. He estado usando MySQL casi exclusivamente durante unos años. –

Cuestiones relacionadas