[英]PostgreSQL GIN index slower than GIST for pg_trgm?
尽管所有文档都说了些什么,但我发现 GIN 索引比 pg_trgm 相关搜索的 GIST 索引慢得多。 这是一个包含 2500 万行的表格,其中包含一个相对较短的文本字段(平均长度为 21 个字符)。 大多数文本行都是“123 Main st, City”形式的地址。
GIST 索引大约需要 4 秒,搜索如下
select suggestion from search_suggestions where suggestion % 'seattle';
但是当使用EXPLAIN ANALYZE
运行时,GIN 需要 90 秒和以下结果:
Bitmap Heap Scan on search_suggestions (cost=330.09..73514.15 rows=25043 width=22) (actual time=671.606..86318.553 rows=40482 loops=1)
Recheck Cond: ((suggestion)::text % 'seattle'::text)
Rows Removed by Index Recheck: 23214341
Heap Blocks: exact=7625 lossy=223807
-> Bitmap Index Scan on tri_suggestions_idx (cost=0.00..323.83 rows=25043 width=0) (actual time=669.841..669.841 rows=1358175 loops=1)
Index Cond: ((suggestion)::text % 'seattle'::text)
Planning time: 1.420 ms
Execution time: 86327.246 ms
请注意,索引选择了超过一百万行,即使实际上只有 40k 行匹配。 任何想法为什么这表现如此糟糕? 这是在 PostgreSQL 9.4 上。
一些问题很突出:
首先,考虑升级到当前版本的 Postgres 。 在撰写本文时,它是第 9.6 页或第 10 页(目前是测试版)。 自 Pg 9.4 以来,对 GIN 索引、附加模块 pg_trgm 和大数据进行了多项改进。
接下来,您需要更多RAM ,尤其是更高的work_mem
设置。 我可以从EXPLAIN
输出中的这一行看出:
Heap Blocks: exact=7625 lossy=223807
位图堆扫描(使用您的特定数字)的详细信息中的“有损”表明work_mem
严重短缺。 Postgres 只收集位图索引扫描中的块地址,而不是行指针,因为使用较低的work_mem
设置(不能在 RAM 中保存确切地址)预计会更快。 在下面的位图堆扫描中,必须以这种方式过滤更多不合格的行。 这个相关的答案有详细信息:
但是不要在不考虑整个情况的情况下将work_mem
设置work_mem
太高:
可能还有其他问题,例如索引或表膨胀或更多配置瓶颈。 但是,如果你只是解决这两个项目,查询要快很多了。
另外,您真的需要检索示例中的所有 40k 行吗? 你可能要一个小添加LIMIT
的查询,使之成为“近邻”搜索-在这种情况下,其主旨在于指数毕竟是更好的选择,因为这应该是与要旨的索引快。 例子:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.