【问题标题】:PostgreSQL GIN index slower than GIST for pg_trgm?PostgreSQL GIN 索引比 pg_trgm 的 GIST 慢?
【发布时间】:2017-03-24 20:14:34
【问题描述】:

尽管所有文档都这么说,我发现 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 上。

【问题讨论】:

标签: sql postgresql indexing pattern-matching postgresql-performance


【解决方案1】:

有些问题很突出:

首先,考虑升级到当前版本的 Postgres。在撰写本文时,这是 pg 9.6 或 pg 10(当前为测试版)。自 Pg 9.4 以来,对 GIN 索引、附加模块 pg_trgm 和大数据进行了多项改进。

接下来,您需要更多的 RAM,尤其是更高的 work_mem 设置。我可以从EXPLAIN 输出中的这一行看出:

Heap Blocks: exact=7625 lossy=223807

“有损”Bitmap Heap Scan 的详细信息中(带有您的特定数字)表示 work_mem 的严重短缺。 Postgres 仅在位图索引扫描中收集块地址而不是行指针,因为使用较低的work_mem 设置(不能在 RAM 中保存确切地址)预计会更快。更多不符合条件的行必须以这种方式在以下位图堆扫描中进行过滤。这个相关的答案有详细信息:

但是不要把work_mem设置得太高不考虑整体情况:

可能还有其他问题,例如索引或表膨胀或更多配置瓶颈。但是如果你只修复这两个项目,查询应该已经快很多了。

另外,您真的需要检索示例中的所有 40k 行吗?您可能希望在查询中添加一个小的 LIMIT 并使其成为“最近邻”搜索 - 在这种情况下,GiST 索引毕竟是更好的选择,因为 /em> 应该使用 GiST 索引更快。示例:

【讨论】:

  • 非常感谢!机器有足够的内存,所以我会尝试增加 work_mem 设置。最终查询将使用限制,为简单起见,我将其从示例中删除 - 添加它不会更改查询计划(除了明显添加限制)。
猜你喜欢
  • 2015-05-12
  • 1970-01-01
  • 2019-11-12
  • 1970-01-01
  • 2014-01-02
  • 2020-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多