1

我正在我们的系统中使用 ILIKE 进行模式匹配搜索,但是由于表中的记录数量,它对某些表来说太慢了。所以我正在按照这篇文章https://www.depesz.com/2011/02/19/waiting-for-9-1-faster-likeilike/中的说明实施三元索引。我没有使用全文搜索,因为我需要像 '%xxx%' 这样的搜索,而全文搜索不能很好地使用它。测试表有 16000 条记录,我在表中创建了一个新列,用于连接其他一些列的搜索。

我已经进行了一些测试,这是结果:

SELECT * FROM "table" WHERE "searchField" ILIKE '%ose%'

无索引 1639 行 30.3 秒。平均

GIN INDEX 1639 行 26.4 秒。平均

SELECT * FROM "table" WHERE "searchField" ILIKE '%ose%' OR "searchField" ILIKE '%ria%'

无索引 1639 行 3:02 分钟。平均

GIN INDEX 1639 行 2.56 分钟。平均

正如你所看到的,这不是一个很好的改进,帖子说查询时间减少到毫秒。解释分析表明:

Bitmap Heap Scan on "table"  (cost=22.31..1827.93 rows=1331 width=511)
                             (actual time=0.354..4.644 rows=1639 loops=1)
  Recheck Cond: (("searchField")::text ~~* '%ose%'::text)
  Heap Blocks: exact=585
  ->  Bitmap Index Scan on "table_trgm_gin"  (cost=0.00..21.98 rows=1331 width=0)
                                             (actual time=0.276..0.276 rows=1639 loops=1)
        Index Cond: (("searchField")::text ~~* '%ose%'::text)

索引扫描很快,但条件重新检查太慢。我读过由于误报的可能性,重新检查是不可避免的。但是我不知道如何获得更好的结果。

谁能解释为什么索引没有太大区别以及如何获得更好的查询时间?

4

1 回答 1

0

您显示的EXPLAIN (ANALYZE)必须来自不同的表,因为那里的持续时间不到 5 毫秒。

我注意到您搜索的模式非常短(3 个字符)。

Trigram 索引对于短模式表现不佳,因为在索引扫描期间许多行将匹配并且所有这些行都必须重新检查。

有两件事要检查我的分析是否正确:

  • 使用更长的模式进行测试,看看性能是否有所提高。
  • 查看EXPLAIN (ANALYZE)耗时三分钟的查询的输出,看看在索引扫描期间是否发现了很多行。

如果我是对的,那么你无能为力。寻找短模式只是表现不佳。您可以尝试限制模式中字符的最小长度以避免该问题。

于 2017-11-27T21:28:52.603 回答