2009-10-08 131 views
15

我使用來自StackOverflow的9月數據轉儲作爲示例數據來測試PostgreSQL文本搜索功能。 :-)爲什麼PostgreSQL文本搜索GiST索引比GIN索引慢得多?

使用LIKE謂詞或POSIX正則表達式匹配搜索120萬行的簡易方法需要大約90-105 (我的MacBook上)做一個全表掃描搜索的關鍵字。

SELECT * FROM Posts WHERE body LIKE '%postgresql%'; 
SELECT * FROM Posts WHERE body ~ 'postgresql'; 

未編制索引,特設文本的搜索查詢約需8分鐘

SELECT * FROM Posts WHERE to_tsvector(body) @@ to_tsquery('postgresql'); 

創建GIN索引需要大約40分鐘

ALTER TABLE Posts ADD COLUMN PostText TSVECTOR; 
UPDATE Posts SET PostText = to_tsvector(body); 
CREATE INDEX PostText_GIN ON Posts USING GIN(PostText); 

(我意識到我也可以通過將其定義爲表達式索引來一步完成此操作。)

之後,由GIN索引幫助查詢運行速度快了很多 - 大約需要40毫秒

SELECT * FROM Posts WHERE PostText @@ 'postgresql'; 

但是,當我創建梗概指數,結果卻大相徑庭。整個過程不到2分鐘創建索引:

CREATE INDEX PostText_GIN ON Posts USING GIST(PostText); 

之後,使用@@文本的搜索運算符的查詢需要90-100秒。因此,GiST索引確實將未索引的TS查詢從8分鐘改進爲1.5分鐘。但是用LIKE做全表掃描沒有什麼改進。它在Web編程環境中無用。

我錯過了使用GiST索引至關重要的東西嗎?索引是否需要預先緩存在內存中?我從MacPorts使用普通的PostgreSQL安裝,沒有任何調整。

推薦使用GiST索引的方法是什麼?還是每個人使用PostgreSQL做TS都跳過GiST索引並只使用GIN索引? PS:我知道像Sphinx Search和Lucene這樣的替代品。我只是想了解PostgreSQL本身提供的功能。

回答

5

嘗試

CREATE INDEX PostText_GIST ON Posts USING GIST(PostText varchar_pattern_ops); 

它創建適合前綴查詢索引。請參閱Operator Classes and Operator Families上的PostgreSQL文檔。 @@運算符只對term矢量有意義; GiST索引(使用varchar_pattern_ops)將會給LIKE帶來極好的結果。

+0

謝謝您的回答部分,我我會嘗試你的建議... – 2009-10-09 20:35:03

+1

它必須花費相當多的時間才能生成該索引。 :) – 2009-12-11 03:56:40

+5

這不可能工作,因爲'varchar_pattern_ops'用於'varchar'類型,'PostText'是'tsvector'類型,它只被定義爲'btree'和'hash'索引而不是'gist'。 – 2011-01-04 20:22:13

2

順便說一句:如果沒有得到回答讓您滿意的是,在這裏你做

SELECT * FROM Posts WHERE PostText @@ 'postgresql';

應該已經

SELECT * FROM Posts WHERE PostText @@ to_tsquery('postgresql');

+0

感謝您的提示,下次我測試PostgreSQL時我會嘗試一下。我幾年來一直在使用MySQL。 – 2013-07-18 18:25:43