2009-10-08 7 views
15

Je suis en train de tester les fonctionnalités de recherche de texte de PostgreSQL, en utilisant le fichier de données de septembre de StackOverflow comme exemple de données. :-)Pourquoi les index PostgreSQL Text-Search GiST sont-ils tellement plus lents que les index GIN?

L'approche naïve de l'utilisation LIKE prédicats ou une expression régulière correspondant à la recherche Posix 1,2 million de lignes prend environ 90-105 secondes (sur mon macbook) pour faire une table-analyse complète la recherche d'un mot-clé.

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

Un non indexé, requête ad hoc texte recherche prend environ 8 minutes:

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

Création d'un index GIN prend environ 40 minutes:

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

(I je réalise que je pourrais aussi le faire en une étape en le définissant comme un index d'expression.)

Ensuite, une requête assistée par un index GIN va beaucoup plus vite - cela prend environ 40 millisecondes :

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

Cependant, lorsque je crée un index GiST, les résultats sont tout à fait différents. Il faut moins de 2 minutes pour créer l'index:

CREATE INDEX PostText_GIN ON Posts USING GIST(PostText); 

Ensuite, une requête en utilisant l'opérateur de recherche de texte @@ prend 90-100 secondes. Les index GiST améliorent donc une requête TS non indexée de 8 minutes à 1,5 minute. Mais ce n'est pas une amélioration par rapport à une analyse de table complète avec LIKE. C'est inutile dans un environnement de programmation web. Ai-je besoin de quelque chose de crucial pour utiliser les index GiST? Les index doivent-ils être pré-mis en cache en mémoire ou quelque chose? J'utilise une installation PostgreSQL simple de MacPorts, sans réglage.

Quelle est la méthode recommandée pour utiliser les index GiST? Ou tout le monde qui fait TS avec PostgreSQL saute-t-il les index GiST et n'utilise que des index GIN? PS: Je connais des alternatives comme Sphinx Search et Lucene. J'essaie juste de connaître les fonctionnalités de PostgreSQL.

Répondre

5

essayer

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

qui crée un index approprié pour les requêtes de préfixe. Voir les documents PostgreSQL sur Operator Classes and Operator Families. L'opérateur @@ est seulement sensible sur les vecteurs de terme; l'index GiST (avec varchar_pattern_ops) donnera d'excellents résultats avec LIKE.

+0

Merci pour votre réponse, je m va essayer votre suggestion ... –

+1

Cela a dû prendre un certain temps pour générer cet index. :) –

+5

Cela ne peut pas fonctionner car 'varchar_pattern_ops' est de type' varchar', et 'PostText' est de type' tsvector', et il est seulement défini pour les index 'btree' et' hash' et non pour 'gist'. –

2

BTW: si cela n'a pas été répondu à votre satisfaction encore, la partie où vous avez fait

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

aurait dû être

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

+0

Merci pour le conseil, je vais essayer cela la prochaine fois que je testerai PostgreSQL. J'ai utilisé MySQL à peu près exclusivement pendant quelques années. –