为什么PostgreSQL Text-Search GiST索引比GIN索引慢得多?

时间:2009-10-08 20:49:58

标签: performance postgresql full-text-search

我正在测试PostgreSQL文本搜索功能,使用StackOverflow的9月数据转储作为样本数据。 : - )

使用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'; 

但是,当我创建GiST索引时,结果会有很大差异。创建索引需要不到 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本身提供的功能。

3 个答案:

答案 0 :(得分:6)

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

创建适合前缀查询的索引。请参阅Operator Classes and Operator Families上的PostgreSQL文档。 @@运算符仅对术语向量有意义;使用LIKE,GiST索引(使用varchar_pattern_ops)将获得出色的结果。

答案 1 :(得分:6)

如果您感兴趣,文档可以很好地概述GiST和GIN索引之间的性能差异:GiST and GIN Index Types

答案 2 :(得分:2)

顺便说一下:如果你还没有得到满意的回答,你所做的部分

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

应该是

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