2

儘管所有的文檔都說,我發現GIN索引比pg_trgm相關搜索的GIST索引慢得多。這是一張2500萬行的表格,文字字段相對較短(平均長度爲21個字符)。大部分文本行都是「123 Main St,City」形式的地址。PostgreSQL的GIN索引比GIST的pg_trgm慢?

GIST指數大約需要4秒,像

select suggestion from search_suggestions where suggestion % 'seattle'; 

一個搜索,但GIN需要90秒,然後EXPLAIN ANALYZE運行時,下面的結果:

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

一些信息的性能問題是缺少。表定義,表和索引的總大小。 [見說明這裏。](https://stackoverflow.com/tags/postgresql-performance/info) –

回答

0

的一些問題比較突出:

首先考慮升級到Postgres的的當前版本。在撰寫本文時,第9.6或第10頁(目前爲測試版)。從Pg 9.4開始,對GIN索引,附加模塊pg_trgm和大數據進行了多次改進。

接下來,你需要更多的RAM,特別是較高的work_mem設置。我可以從該線路EXPLAIN輸出告訴:

Heap Blocks: exact=7625 lossy=223807 

「有損」在一個位圖堆掃描(根據您的特定編號)的細節表示work_mem一個急劇短缺。 Postgres僅在位圖索引掃描中收集塊地址而不是行指針,因爲在設置較低的work_mem(無法在RAM中保存精確地址)時,該地址會更快。在這種方式下,以下位圖堆掃描必須過濾更多不合格行。該相關答案有更多的細節:

但不設置work_mem高不考慮整體情況:

有可能其他問題,如索引o表臃腫或更多配置瓶頸。但是,如果你只修復這兩個項目,查詢應該是更快已經更快。

另外,你是否真的需要檢索示例中的所有40k行?您可能想要將一個小的LIMIT添加到查詢中,並將其設置爲「最近鄰居」搜索 - 在這種情況下,GiST索引畢竟是更好的選擇,因爲那個應該更快,而且GiST索引。例如:

+0

非常感謝!該機器有很多內存,所以我會嘗試增加work_mem設置。最後的查詢將使用一個限制,爲了簡化,我將它從示例中刪除了 - 添加它並沒有改變查詢計劃(除了顯而易見的額外限制)。 – Doug