development

Heroku에서 PostgreSQL의 내장 전체 텍스트 검색을 사용하지 않는 이유는 무엇입니까?

big-blog 2020. 12. 8. 18:54
반응형

Heroku에서 PostgreSQL의 내장 전체 텍스트 검색을 사용하지 않는 이유는 무엇입니까?


전체 텍스트 검색이 필요한 Heroku에 Rails 앱을 배포 할 준비를하고 있습니다. 지금까지 Sphinx와 함께 MySQL을 사용하여 VPS에서 실행했습니다.

그러나 Heroku에서 Sphinx 또는 Solr을 사용하려면 추가 기능 비용을 지불해야합니다.

PostgreSQL (Heroku에서 사용되는 DB)에는 전체 텍스트 검색 기능이 내장되어 있습니다.

Postgres의 전체 텍스트 검색을 사용할 수없는 이유가 있습니까? 스핑크스보다 느리거나 다른 주요 제한 사항이 있습니까?


편집, 2016 — 둘 다 아닌 이유는 무엇입니까?

Postgres 대 Lucene에 관심이 있다면 둘 다 아닌 이유는 무엇입니까? Elasticsearch를 일류 인덱스 유형으로 통합하는 Postgres 용 ZomboDB 확장을 확인하십시오 . 아직 초기 프로젝트이지만 나에게 정말 유망 해 보입니다.

(기술적으로 Heroku에서는 사용할 수 없지만 살펴볼 가치가 있습니다.)


공개 : 저는 WebsolrBonsai Heroku 애드온 의 공동 창립자 이므로 제 관점은 Lucene에 약간 편향되어 있습니다.

Postgres 전체 텍스트 검색에 대한 필자는 간단한 사용 사례에 대해서는 상당히 견고하지만 Lucene (및 따라서 Solr 및 ElasticSearch)이 성능과 기능면에서 모두 우수한 이유는 여러 가지가 있습니다.

우선, jpountz 는 Solr이 Postgres보다 훨씬 빠른 이유 라는 질문에 대한 진정으로 뛰어난 기술적 답변을 제공합니다 . 실제로 소화하기 위해 몇 번 읽어 볼 가치가 있습니다.

또한 Postgres 전체 텍스트 검색과 Solr의 상대적인 장점과 단점을 비교 최근 RailsCast 에피소드 에 대해 언급했습니다 . 여기서 요약하겠습니다.

Postgres의 실용적인 이점

  • 다른 것을 설정하고 유지 (또는 비용을 지불)하는 대신 이미 실행중인 기존 서비스를 재사용하십시오.
  • 환상적으로 느린 SQL LIKE연산자 보다 훨씬 뛰어납니다 .
  • 데이터가 모두 동일한 데이터베이스에 있기 때문에 데이터를 동기화 상태로 유지하는 번거 로움이 적습니다. 일부 외부 데이터 서비스 API와 애플리케이션 수준의 통합이 없습니다.

Solr (또는 ElasticSearch)의 장점

내 머리 꼭대기에서, 특별한 순서없이…

  • 일반 데이터베이스로드와 별도로 인덱싱 및 검색로드를 확장합니다.
  • 악센트 정규화, 언어 형태소 분석, N- 그램, 마크 업 제거와 같은 항목에 대한보다 유연한 용어 분석… 맞춤법 검사, "풍부한 콘텐츠"(예 : PDF 및 Word) 추출과 같은 기타 멋진 기능…
  • Solr / Lucene은 Postgres 전체 텍스트 검색 TODO 목록의 모든 작업을 잘 수행 할 수 있습니다 .
  • 검색 시간에 효율적으로 사용자 정의 할 수있는 훨씬 우수하고 빠른 용어 관련성 순위.
  • 일반적인 용어 나 복잡한 쿼리에 대한 검색 성능이 더 빠를 것입니다.
  • 아마도 Postgres보다 더 효율적인 인덱싱 성능입니다.
  • 기본 데이터 저장소에서 인덱싱을 분리하여 데이터 모델 변경에 대한 내성 향상

분명히 Lucene 기반의 전용 검색 엔진이 여기에서 더 나은 옵션이라고 생각합니다. 기본적으로 Lucene은 검색 전문 지식의 사실상의 오픈 소스 저장소로 생각할 수 있습니다.

그러나 유일한 다른 옵션이 LIKE연산자 인 경우 Postgres 전체 텍스트 검색이 확실한 승리입니다.


탄력적 검색 (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

In order to get postgres to these speeds for faceted searches I had to use an GIN index on the field with a SearchVectorField, which is django specific but I'm sure other frameworks have a similar vector type.

One other consideration is that pg 9.6 now supports phrase matching, which is huge.

My take away is that postgres is for most cases going to be preferrable as it offers:

  1. simpler stack
  2. no search backend api wrapper dependencies to contend with (thinking-sphinx, django-sphinx, haystack etc.). These can be a drag since they might not support the features your search back-end does (e.g. haystack faceting/aggregates).
  3. has similar performance and features (for my needs)

I found this amazing comparison and want to share it:

Full Text Search In PostgreSQL

Time to Build Index LIKE predicate -- none
PostgreSQL / GIN -- 40 min
Sphinx Search -- 6 min
Apache Lucene -- 9 min
Inverted index -- high

Index Storage LIKE predicate -- none
PostgreSQL / GIN -- 532 MB
Sphinx Search -- 533 MB
Apache Lucene -- 1071 MB
Inverted index -- 101 MB

Query Speed LIKE predicate -- 90+ seconds
PostgreSQL / GIN -- 20 ms
Sphinx Search -- 8 ms
Apache Lucene -- 80 ms
Inverted index -- 40 ms


Postgres's full text search has amazing capabilities in the areas of stemming, ranking/boosting, synonym handling, fuzzy searches among others - but no support for faceted search.

So, if Postgres is already in your stack and you don't need faceting, better try it out to avail the HUGE benefit of ease of keeping indices in sync and maintaining sleek stack, before looking out for Lucene based solutions - at least if all your app is not based on search.


Postgresql's FTS function is mature and fairly fast at lookups. It's worth a look for sure.

참고URL : https://stackoverflow.com/questions/10875674/any-reason-not-use-postgresqls-built-in-full-text-search-on-heroku

반응형