J'ai rencontré la recherche en texte intégral dans postgres au cours des derniers jours, et je suis un peu confus quant à l'indexation lors de la recherche sur plusieurs colonnes.
Les documents postgres parlent de la création d'un ts_vector
index sur des colonnes concaténées, comme ceci:
CREATE INDEX pgweb_idx ON pgweb
USING gin(to_tsvector('english', title || ' ' || body));
que je peux rechercher ainsi:
... WHERE
(to_tsvector('english', title||' '||body) @@ to_tsquery('english', 'foo'))
Cependant, si je voulais parfois rechercher uniquement le titre, parfois simplement le corps, et parfois les deux, j'aurais besoin de 3 index distincts. Et si j'ajoutais dans une troisième colonne, cela pourrait potentiellement être 6 index, et ainsi de suite.
Une alternative que je n'ai pas vue dans les documents est simplement d'indexer les deux colonnes séparément, puis d'utiliser simplement une WHERE...OR
requête normale :
... WHERE
(to_tsvector('english', title) @@ to_tsquery('english','foo'))
OR
(to_tsvector('english', body) @@ to_tsquery('english','foo'))
L'analyse comparative des deux sur environ 1 million de lignes semble n'avoir pratiquement aucune différence de performances.
Ma question est donc:
Pourquoi voudrais-je concaténer des index comme celui-ci, plutôt que d'indexer les colonnes individuellement? Quels sont les avantages / inconvénients des deux?
Ma meilleure supposition est que si je savais à l'avance, je ne voudrais que rechercher les deux colonnes (jamais une à la fois) Je n'aurais besoin que d'un index en concaténant qui utilise moins de mémoire.
la source
title
dansbody
puis de l'indexation qui donnerait beaucoup de valeur, même si je suis ouvert à la correction. Je me contenterais probablement de les indexer séparément. De plus, si c'était une opération unique loufoque qui vous obligeait à concaténer, je suppose que vous pourriez simplement exécuter la requête ad hoc.Réponses:
Non, vous n'avez pas besoin d'index séparés. Utilisez la fonction de pondération. Ils ne sont qu'une étiquette contre laquelle vous pouvez interroger. Vous pouvez avoir jusqu'à quatre étiquettes pour interroger (AD).
Vous souhaiterez peut-être concaténer des vecteurs ts afin de pouvoir leur appliquer séparément des pondérations, puis les regrouper:
la source
En fait, l'alternative serait d'utiliser où avec OU , et non ET .
Si vous avez un index sur tsvector (corps + titre) et que vous recherchez dedans, les mots recherchés peuvent être dans le titre OU dans le corps.
Aussi - lors des tests, assurez-vous d'avoir un nombre raisonnable de lignes dans le tableau.
Cas le plus simple qui devrait montrer une bonne différence: trouvez deux mots - l'un d'eux est très susceptible d'être dans le titre. et l'autre - qui est très susceptible d'être dans le corps. Mais assurez-vous qu'il n'y a pas beaucoup de lignes qui correspondent aux deux critères. Par exemple, vous pourriez avoir 30% du mot "depesz" dans le corps. Vous avez également ~ 30% de chances d'avoir "mysql" dans le titre. Mais avoir "depesz et mysql" dans l'un des champs de la même ligne est très peu probable. Et puis vérifiez les performances avec de tels index.
la source