我使用来自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