2

모든 문서에 언급 된 내용에도 불구하고 GIN 인덱스가 pg_trgm 관련 검색의 GIST 인덱스보다 상당히 느리다는 것을 알게되었습니다. 이것은 비교적 짧은 텍스트 필드 (평균 길이 21 자)가있는 2 천 5 백만 행의 표에 있습니다. 대부분의 텍스트 행은 "123 Main st, City"형식의 주소입니다.PostgreSQL GIN 색인이 pg_trgm에 대해 GIST보다 느립니다.

GIST 지수는

select suggestion from search_suggestions where suggestion % 'seattle'; 

같은 검색을 약 4 초 정도 걸립니다 그러나 GIN은 90 초 정도 걸리며 다음과 같은 결과가 EXPLAIN ANALYZE으로 실행하는 경우 : 100 만 이상 행이되고 있다는

Bitmap Heap Scan on search_suggestions (cost=330.09..73514.15 rows=25043 width=22) (actual time=671.606..86318.553 rows=40482 loops=1) 
    Recheck Cond: ((suggestion)::text % 'seattle'::text) 
    Rows Removed by Index Recheck: 23214341 
    Heap Blocks: exact=7625 lossy=223807 
    -> Bitmap Index Scan on tri_suggestions_idx (cost=0.00..323.83 rows=25043 width=0) (actual time=669.841..669.841 rows=1358175 loops=1) 
     Index Cond: ((suggestion)::text % 'seattle'::text) 
Planning time: 1.420 ms 
Execution time: 86327.246 ms 

주 실제로 40k 행만 일치하더라도 색인에 의해 선택됩니다. 이것이 왜 그렇게 잘 수행되지 않는가? 이것은 PostgreSQL 9.4에 있습니다.

+0

성능 질문에 대한 일부 정보가 누락되어있다. 테이블 정의, 테이블 및 인덱스의 전체 크기. [여기 지침을 참조하십시오.] –

답변

0

일부 문제가 눈에 띄는 :

첫째, 포스트 그레스의 최신 버전으로 업그레이드하는 것이 좋습니다. 필자는 현재 9.6 또는 10 (현재 베타 버전)입니다. 페이지 9.4부터는 GIN 인덱스, 추가 모듈 pg_trgm 및 일반적으로 큰 데이터에 대해 여러 가지 개선 사항이있었습니다.

다음, 당신은 특히 높은 work_mem 설정을 훨씬 더 RAM이 필요합니다. 나는 EXPLAIN 출력이 줄에서 알 수 있습니다 :

Heap Blocks: exact=7625 lossy=223807 

"손실"을 (특정 번호)를 비트 맵 힙 스캔에 대한 세부 사항에 work_mem의 극적인 부족을 나타냅니다. Postgres는 로우 포인터 대신 비트 맵 인덱스 스캔에서 블록 주소만을 수집하기 때문에 낮은 주소 인 work_mem 설정 (RAM에 정확한 주소를 저장할 수 없음)이 빠를 것으로 예상됩니다. 더 많은 비 한정 행은 다음과 같이 비트 맵 힙 스캔에서 필터링해야합니다.

하지만 전체 상황을 고려하지 않고 너무 높은을 work_mem을 설정하지 :

이 월을이 관련 답변은 세부 사항을 가지고 색인 같은 다른 문제들 테이블이 부풀거나 더 많은 구성 병목 현상이 발생합니다. 그러나이 두 항목 만 수정하면 쿼리는 이 훨씬 빨라야합니다.

또한 예제에서 40k 행을 모두 검색해야합니까? LIMIT을 쿼리에 추가하여 "가장 가까운 이웃"검색으로 지정하는 것이 좋습니다.이 경우 인 GiST 색인으로 더 빠르기 때문에 GiST 색인이 더 나은 선택입니다 .예 :

+0

정말 고마워요! 컴퓨터에는 충분한 메모리가 있으므로 work_mem 설정을 늘려 보겠습니다. 최종 쿼리는 한도를 사용하고 단순화를 위해 예제에서 제외했습니다. 추가로 제한 계획을 변경하지 않고 쿼리 계획을 변경하지 않았습니다. – Doug