Une raison de ne pas utiliser la recherche en texte intégral de PostgreSQL sur Heroku?
je me prépare à déployer une application Rails sur Heroku qui nécessite une recherche plein texte. Jusqu'à présent je l'ai lancé sur un VPS en utilisant MySQL avec Sphinx.
cependant, si je veux utiliser Sphinx ou Solr sur Heroku, je dois payer pour un add-on.
je remarque que PostgreSQL (le DB utilisé sur Heroku) a intégré la capacité de recherche plein texte.
y a-t-il une raison pour que je ne puisse pas utiliser la recherche en texte intégral de Postgres? Est-il plus lent que Sphinx ou y a-t-il une autre limitation majeure?
5 réponses
Modifier la, À 2016 Pourquoi pas les deux?
si vous êtes intéressé par Postgres contre Lucene, pourquoi pas les deux? Consultez l'extension ZomboDB pour Postgres, qui intègre Elasticsearch comme un type d'indice de première classe. C'est encore un projet assez précoce, mais il me semble très prometteur.
(techniquement non disponible le Heroku, mais ça vaut le coup de regarder.)
Divulgation: je suis le co-fondateur de la Websolr et Bonsaï Heroku add-ons, donc mon point de vue est un peu biaisé: Lucene.
ma lecture sur la recherche Postgres plein texte est qu'il est assez solide pour les cas d'utilisation simple, mais il ya un certain nombre de raisons pour lesquelles Lucene (et donc Solr et ElasticSearch) est supérieur à la fois en termes de performance et fonctionnalité.
Pour commencer, jpountz fournit une excellente technique de répondre à la question, Pourquoi est-Solr beaucoup plus rapide que Postgres? ça vaut bien quelques lectures pour vraiment digérer.
j'ai également fait des commentaires sur un récente RailsCast épisode la comparaison des avantages et inconvénients de Postgres la recherche de texte intégral rapport à Solr. Permettez-moi de récapituler qu'ici:
avantages Pragmatiques pour Postgres
- réutilisez un service existant que vous utilisez déjà au lieu de configurer et de maintenir (ou de payer) autre chose.
- bien supérieur à L'opérateur incroyablement lent SQL
LIKE
. - moins de tracas à synchroniser les données puisqu'elles sont toutes dans la même base de données - pas d'intégration au niveau de l'application avec certaines API de service de données externes.
avantages de Solr (ou ElasticSearch)
sur le dessus de ma tête, sans ordre particulier ...
- mettez à L'échelle votre charge d'indexation et de recherche séparément de votre charge de base de données régulière.
- une analyse plus souple des termes pour des choses comme la normalisation de l'accent, l'ancrage linguistique, les N-grammes, la suppression du markup... D'autres caractéristiques cools comme la vérification orthographique, le "contenu riche" (p. ex., PDF et l'extraction de mots) …
- Solr/Lucene pouvez tout faire sur le Postgres la recherche de texte intégral TODO list l'amende juste.
- beaucoup mieux et plus rapide de classement de pertinence terme, efficacement personnalisable au moment de la recherche.
- performance de recherche probablement plus rapide pour des termes communs ou des requêtes compliquées.
- probablement plus efficace de performance d'indexation que Postgres.
- une meilleure tolérance au changement dans votre modèle de données en découplant l'indexation de votre mémoire primaire
clairement, je pense qu'un moteur de recherche dédié basé sur Lucene est la meilleure option ici. Fondamentalement, vous pouvez penser à Lucene comme le dépôt de facto open source de l'expertise de recherche.
mais si votre seule autre option est l'opérateur LIKE
, alors la recherche en texte intégral de Postgres est une victoire certaine.
puisque je viens de passer par l'effort de comparer la recherche élastique (1.9) contre les FTS de postgres, j'ai pensé que je devrais partager mes résultats car ils sont un peu plus actuels que ceux que @gustavodiazjaimes cite.
ma principale préoccupation avec postgres était qu'il n'y avait pas de façade construite dedans, mais c'est trivial pour construire vous-même, voici mon exemple (en django):
results = YourModel.objects.filter(vector_search=query)
facets = (results
.values('book')
.annotate(total=Count('book'))
.order_by('book'))
j'utilise postgres 9.6 et elastic-search 1.9 (par haystack on django). Voici une comparaison entre elasticsearch et postgres à travers 16 différents types de requêtes.
es_times pg_times es_times_faceted pg_times_faceted
0 0.065972 0.000543 0.015538 0.037876
1 0.000292 0.000233 0.005865 0.007130
2 0.000257 0.000229 0.005203 0.002168
3 0.000247 0.000161 0.003052 0.001299
4 0.000276 0.000150 0.002647 0.001167
5 0.000245 0.000151 0.005098 0.001512
6 0.000251 0.000155 0.005317 0.002550
7 0.000331 0.000163 0.005635 0.002202
8 0.000268 0.000168 0.006469 0.002408
9 0.000290 0.000236 0.006167 0.002398
10 0.000364 0.000224 0.005755 0.001846
11 0.000264 0.000182 0.005153 0.001667
12 0.000287 0.000153 0.010218 0.001769
13 0.000264 0.000231 0.005309 0.001586
14 0.000257 0.000195 0.004813 0.001562
15 0.000248 0.000174 0.032146 0.002246
count mean std min 25% 50% 75% max
es_times 16.0 0.004382 0.016424 0.000245 0.000255 0.000266 0.000291 0.065972
pg_times 16.0 0.000209 0.000095 0.000150 0.000160 0.000178 0.000229 0.000543
es_times_faceted 16.0 0.007774 0.007150 0.002647 0.005139 0.005476 0.006242 0.032146
pg_times_faceted 16.0 0.004462 0.009015 0.001167 0.001580 0.002007 0.002400 0.037876
pour obtenir des postgres à ces vitesses pour des recherches facettées, j'ai dû utiliser un index GIN sur le champ avec un SearchVectorField, qui est spécifique à django mais je suis sûr que d'autres cadres ont un type de vecteur similaire.
une autre considération est que la page 9.6 supporte maintenant l'appariement de phrase, qui est énorme.
de Mon point de vue que postgres est pour la plupart des cas va être préférable qu'il propose:
- simple pile
- pas de recherche backend api wrapper dépendances composer avec (pensée-sphinx, django-sphinx, botte de foin, etc.). Il peut s'agir d'une traînée, car ils ne supportent peut-être pas les fonctionnalités de l'arrière-plan de votre recherche (p. ex., façonnage/agrégats de meules de foin).
- a des performances et des caractéristiques similaires (pour mes besoins)
j'ai trouvé cette comparaison étonnante et je veux la partager:
Recherche En Texte Intégral Dans PostgreSQL
du Temps pour Construire l'Indice de prédicat LIKE -- aucun
PostgreSQL / GIN -- 40 min
Recherche Sphinx -- 6 min
Apache Lucene -- 9 min
Indice inversé -- élevé
indice de stockage comme prédicate -- aucun
PostgreSQL / GIN -- 532 MB
Sphinx Search -- 533 MB
Apache Lucene -- 1071 MB
Indice inversé -- 101 MB
la Vitesse des Requêtes COMME prédicat -- 90+ secondes
PostgreSQL / GIN -- 20 ms
Sphinx Search -- 8 ms
Apache Lucene -- 80 ms
Indice inversé -- 40 ms
la recherche en texte intégral de Postgres a des capacités étonnantes dans les domaines de l'émulation, du classement/de l'amplification, de la manipulation de synonymes, des recherches floues entre autres - mais aucun support pour la recherche facettée.
donc, si Postgres est déjà dans votre pile et vous n'avez pas besoin de faceting, mieux l'essayer pour profiter de l'avantage énorme de la facilité de garder les indices dans la synchronisation et le maintien de la pile élégante, avant de regarder dehors pour des solutions basées sur Lucene - au moins si toute votre application n'est pas basée sur la recherche.
Postgresql est mature et assez rapide lors des recherches. Il vaut la peine un coup d'oeil pour vous.