3

postgres trigram 文档指出:

pg_trgm 模块提供 GiST 和 GIN 索引运算符类,允许您在文本列上创建索引,以实现非常快速的相似性搜索。这些索引类型支持上述相似性运算符,并且还支持基于三元组的索引搜索 LIKE、ILIKE、~ 和 ~* 查询。

并显示以下示例:

SELECT t, word_similarity('word', t) AS sml
  FROM test_trgm
  WHERE 'word' <% t
  ORDER BY sml DESC, t;

惊人的!

但是,在运行以下查询时:

SELECT * 
FROM place 
WHERE word_similarity(place.name, '__SOME_STRING__') > 0.5

创建的索引未被使用。

但是,当使用ILIKEor%>运算符时,似乎确实正在使用索引。为什么函数上没有使用索引word_similarity

4

1 回答 1

4

根据this postgres forum response

PostgreSQL 不对 WHERE 子句中的函数使用索引扫描。所以你总是需要使用运算符。您可以尝试 <% 运算符和 pg_trgm.word_similarity_threshold 变量:

=# SET pg_trgm.word_similarity_threshold 为 0.1;

=# SELECT name, popular FROM temp.items3_v ,(values ('some phrase'::text)) consts(input) WHERE input <% name ORDER BY 2, input <<-> name;

因此,可以更新查询以使用索引,如下所示:

SET pg_trgm.word_similarity_threshold TO 0.1;
SELECT * 
FROM place 
WHERE place.name <<-> '__SOME_STRING__';

警告:操作员只使用只有一个版本的换向器对的索引。即,它只使用了 case 中的索引,<<->而不使用了 case <->>This stack overflow q/a post看起来对原因给出了合理的解释:

这些是不同的操作,索引只支持其中一个。

于 2020-02-11T21:12:09.820 回答