2016-11-13 46 views
1

我創建了這樣一個表格,GIN索引有什麼問題,無法避免SEQ掃描?

create table mytable(hash char(40), title varchar(500)); 
create index name_fts on mytable using gin(to_tsvector('english', 'title')); 
CREATE UNIQUE INDEX md5_uniq_idx ON mytable(hash); 

當我查詢的名稱,

test=# explain analyze select * from mytable where to_tsvector('english', title) @@ 'abc | def'::tsquery limit 10; 
                QUERY PLAN 
-------------------------------------------------------------------------------------------------------------------- 
Limit (cost=0.00..277.35 rows=10 width=83) (actual time=0.111..75.549 rows=10 loops=1) 
    -> Seq Scan on mytable (cost=0.00..381187.45 rows=13744 width=83) (actual time=0.110..75.546 rows=10 loops=1) 
     Filter: (to_tsvector('english'::regconfig, (title)::text) @@ '''abc'' | ''def'''::tsquery) 
     Rows Removed by Filter: 10221 
Planning time: 0.176 ms 
Execution time: 75.564 ms 
(6 rows) 

將不使用索引。有任何想法嗎?我有10米行。

+0

這不是全文搜索的工作原理。 – Phill

+0

@Phill你能詳細說明嗎? – daisy

+0

您的查詢在執行時轉換該值,這會很慢,它永遠不會使用索引。您應該將tsvector存儲在表格的單獨列中。 – Phill

回答

1

。在你的索引定義一個錯字,應該是

ON mytable USING gin (to_tsvector('english', title)) 

,而不是

ON mytable USING gin (to_tsvector('english', 'title')) 

你寫它的方式,它是一個常數,而不是被索引的字段,而這樣的索引對於像你所執行的那樣的搜索來說確實沒有用處。

要查看索引可以可以使用,你可以執行

SET enable_seqscan=off; 

,然後再次運行該查詢。
如果仍未使用索引,則索引可能無法使用。

除了上述之外,還有一些東西讓我覺得你的執行計劃很奇怪。 PostgreSQL估計,如您所說,mytable的順序掃描將返回13744行,而不是1000萬。你禁用了autovacuum還是有其他可能會導致你的表統計不準確?

+0

它一旦錯字固定,也'限制10'阻止索引的使用工作。 – daisy