我使用來自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本身提供的功能。
謝謝您的回答部分,我我會嘗試你的建議... – 2009-10-09 20:35:03
它必須花費相當多的時間才能生成該索引。 :) – 2009-12-11 03:56:40
這不可能工作,因爲'varchar_pattern_ops'用於'varchar'類型,'PostText'是'tsvector'類型,它只被定義爲'btree'和'hash'索引而不是'gist'。 – 2011-01-04 20:22:13