Postgresql 9.4:索引在模式搜索中不起作用

Posted

技术标签:

【中文标题】Postgresql 9.4:索引在模式搜索中不起作用【英文标题】:Postgresql 9.4: index not working in a pattern search 【发布时间】:2015-10-09 17:50:23 【问题描述】:

我有一个名为“医生”的表和一个名为“全名”的字段,它将存储带有重音符号的名称。 我需要做的是“不区分重音+不区分大小写”的搜索,例如:

SELECT * 
FROM doctors
WHERE unaccent_t(fullname) ~* 'unaccented_and_lowercase_string';

其中要搜索的值将是非重音+小写,而 unaccent_t 是一个定义为的函数:

CREATE FUNCTION unaccent_t(text, lowercase boolean DEFAULT false)
RETURNS text AS
$BODY$
SELECT CASE
  WHEN $2 THEN unaccent('unaccent', lower(trim($1)))
  ELSE unaccent('unaccent', trim($1))
END;
$BODY$ LANGUAGE sql IMMUTABLE SET search_path = public, pg_temp;

(我已经安装了“unaccent”扩展)。

所以,我继续为“全名”字段创建索引:

CREATE INDEX doctors_fullname ON doctors (unaccent_t(fullname) text_pattern_ops);

(我也尝试过使用 varchar_pattern_ops 并且根本没有指定操作)

在医生表中,我有大约 15K 行。

查询有效,我得到了预期的结果,但是当我将 explain analyze 添加到查询中时,我没有看到使用了索引:

Seq Scan on doctors  (cost=0.00..4201.76 rows=5 width=395) (actual time=0.282..182.025 rows=15000 loops=1)
  Filter: (unaccent_t((fullname)::text, false) ~* 'garcia'::text)
  Rows Removed by Filter: 1
Planning time: 0.207 ms
Execution time: 183.387 ms

我也尝试从 unaccent_t 中删除可选参数,但得到了相同的结果。

在这样的场景中,我应该如何定义索引以便在上述查询中使用它?

【问题讨论】:

此技术可以与= 或左锚LIKE 一起使用,但~* 是用于匹配正则表达式的运算符。 所以试试应该使用索引的SELECT * WHERE name like '%garcia'。但这不会SELECT * WHERE name like 'garcia%' 【参考方案1】:

Btree 索引仅在模式处于锚定状态时可用于加速操作。

从 PostgreSQL 9.3 开始,您可以使用 GIN 或 GiST 索引以及 pg_trgm contrib 模块提供的运算符类来加速通用正则表达式搜索。

您可以在 http://www.postgresql.org/docs/9.4/static/pgtrgm.html#AEN163078 的 PostgreSQL 手册中阅读更多相关信息

【讨论】:

谢谢,这听起来不错。然后,我将为此类搜索创建一个 gin/gist 索引。干杯。 尝试使用_text_ops 创建一个 gin 索引告诉我该运算符不接受文本数据。如果没有指定任何选项,它会告诉我没有默认的运算符类。指定gin_trgm_ops 会创建索引并且它可以工作,但我不会在该字段中进行“trigram”全文搜索。我可以为这个 gin 索引使用另一个运算符类吗?或者即使我不执行任何全文搜索,使用gin_trgm_ops 也可以? 另外,解释分析现在告诉我正在使用索引,但是不使用索引执行时间基本相同。就像索引没有提高查询的执行时间一样。可能出了什么问题? GIN 或 GIST _trgm_ops 索引可用于加速任何正则表达式或 LIKE 搜索。如果生成的执行时间与没有索引的执行时间相似,那可能是因为您的数据集很小,或者因为您选择了大部分数据。 mnencia,这很有意义。我的测试数据属于你提到的。好消息是现在我知道索引正在被使用。所以,在我的查询场景中,这个 gin 索引将完成这项工作。再次感谢。

以上是关于Postgresql 9.4:索引在模式搜索中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

带有 nativeQuery 的 Spring Boot Query 注释在 Postgresql 中不起作用

order by 在 POSTGRESQL 中的 partition by 子句中不起作用?

postgresql----Gist索引

Select2 在引导模式中不起作用

为啥 C++ CLI 索引属性在 C# 中不起作用?

记一次在线安装postgresql-9.4的问题