web-dev-qa-db-ja.com

HerokuでPostgreSQLの組み込み全文検索を使用しない理由はありますか?

全文検索を必要とするHerokuでRailsアプリをデプロイする準備をしています。これまで、MySQLとSphinxを使用してVPSで実行してきました。

ただし、HerokuでSphinxまたはSolrを使用する場合は、アドオンに料金を支払う必要があります。

PostgreSQL(Herokuで使用されるDB)には全文検索機能が組み込まれていることに気付きました。

Postgresの全文検索を使用できなかった理由はありますか? Sphinxより遅いのですか、それとも他の大きな制限がありますか?

57
Ethan

編集、2016 —なぜ両方ではないのですか?

Postgres vs. Luceneに興味があるなら、なぜ両方ではないのですか? Elasticsearchを一流のインデックスタイプとして統合するPostgresの ZomboDB 拡張機能を確認してください。まだかなり初期のプロジェクトですが、本当に有望に見えます。

(技術的にHerokuでは利用できませんが、まだ見る価値があります。)


開示:私は Websolr および Bonsai Herokuアドオンの共同設立者なので、私の視点はLuceneに少し偏っています。

Postgresの全文検索に関する私の記事は、単純なユースケースではかなり安定しているということですが、Lucene(およびSolrとElasticSearch)がパフォーマンスと機能の両方の面で優れている理由はいくつかあります。

手始めに、 jpountz は質問に対する真に優れた技術的回答を提供します。 なぜSolrはPostgresよりもはるかに高速ですか? 本当にダイジェストするための読み取りのカップル。

また、 最近のRailsCastエピソードについてコメントしました Postgres全文検索とSolrの相対的な長所と短所を比較しました。ここで要約します。

Postgresの実用的な利点

  • 他の何かをセットアップして維持する(または料金を支払う)のではなく、既に実行している既存のサービスを再利用します。
  • 驚くほど遅いSQL LIKE演算子よりもはるかに優れています。
  • データはすべて同じデータベースにあるため、データを同期する手間が少なくなります。一部の外部データサービスAPIとのアプリケーションレベルの統合はありません。

Solr(またはElasticSearch)の利点

頭の先から順不同で…

  • インデックス作成と検索の負荷を通常のデータベースの負荷とは別にスケーリングします。
  • アクセントの正規化、言語ステミング、N-gram、マークアップの削除など、より柔軟な用語分析...スペルチェック、「リッチコンテンツ」(例:PDFおよびWord)抽出など)
  • Solr/Luceneは、 Postgres全文検索TODOリスト のすべてをうまく実行できます。
  • 検索時の効率的なカスタマイズが可能な、より適切で高速な用語関連性ランキング。
  • 一般的な用語や複雑なクエリの検索パフォーマンスがおそらく高速になります。
  • おそらくPostgresよりも効率的なインデックス作成パフォーマンス。
  • プライマリデータストアからインデックス付けを分離することにより、データモデルの変更に対する許容度が向上

明らかに、Luceneに基づいた専用の検索エンジンの方が良い選択肢だと思います。基本的に、Luceneは、検索の専門知識の事実上のオープンソースリポジトリと考えることができます。

しかし、他のオプションがLIKE演算子だけである場合、Postgresの全文検索は間違いなく勝利です。

63
Nick Zadrozny

エラスティック検索(1.9)とpostgres FTSを比較する作業を行ったばかりなので、@ gustavodiazjaimesが引用するものよりもやや新しいため、結果を共有する必要があると考えました。

Postgresに対する私の主な懸念は、ファセットが組み込まれていないことでしたが、自分でビルドするのは簡単なことです(Djangoの例):

results = YourModel.objects.filter(vector_search=query)
facets = (results
    .values('book')
    .annotate(total=Count('book'))
    .order_by('book'))

私はpostgres 9.6とelastic-search 1.9を使用しています(Djangoのhaystackを使用)。 16のさまざまなタイプのクエリでのelasticsearchとpostgresの比較を次に示します。

    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

ファセット検索のためにこれらの速度にpostgresを取得するために、SearchVectorFieldを持つフィールドでGINインデックスを使用する必要がありました。これはDjango特定ですが、他のフレームワークも同様のベクトル型を持っていると確信しています。

もう1つの考慮事項は、pg 9.6がフレーズ一致をサポートするようになったことです。これは膨大です。

私の要点は、ほとんどの場合、postgresが次のように優先されることです。

  1. より単純なスタック
  2. 競合する検索バックエンドAPIラッパーの依存関係はありません(thinking-sphinx、Django-sphinx、haystackなど)。検索バックエンドがサポートする機能をサポートしていない可能性があるため、これらはドラッグになる可能性があります(例:haystack faceting/aggregates)。
  3. 同様のパフォーマンスと機能を持っています(私のニーズに合わせて)
19
yekta

この驚くべき比較を見つけたので、共有したいと思います。

PostgreSQLの全文検索

LIKE述語のような索引を作成する時間-なし
PostgreSQL/GIN-40分
スフィンクス検索-6分
Apache Lucene-9分
転置インデックス-高

インデックスストレージLIKE述語-なし
PostgreSQL/GIN-532 MB
Sphinx Search-533 MB
Apache Lucene-1071 MB
転置インデックス-101 MB

クエリ速度LIKE述語-90秒以上
PostgreSQL/GIN-20ミリ秒
Sphinx Search-8ミリ秒
Apache Lucene-80ミリ秒
転置インデックス-40ミリ秒

15

Postgresの全文検索には、ステミング、ランキング/ブースティング、同義語処理、ファジー検索などの分野で素晴らしい機能がありますが、ファセット検索はサポートされていません。

したがって、Postgresが既にスタックにあり、ファセットを必要としない場合は、Luceneベースのソリューションを探す前に、インデックスの同期を維持し、スムーズなスタックを維持するという非常に大きなメリットを活用してください。アプリは検索に基づいていません。

2
Devi

PostgresqlのFTS関数は成熟しており、検索がかなり高速です。確かに一見の価値があります。

0
Scott Marlowe