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

Postgresql 9.4:索引在模式搜索中不起作用,postgresql,postgresql-9.4,Postgresql,Postgresql 9.4,我有一个名为“医生”的表和一个名为“全名”的字段,该字段将存储带有重音符号的名称。 我需要做的是“不区分重音+不区分大小写”的搜索,类似于: SELECT * FROM doctors WHERE unaccent_t(fullname) ~* 'unaccented_and_lowercase_string'; 其中要搜索的值为uncented+小写,uncent是一个定义为: CREATE FUNCTION unaccent_t(text, lowercase boolean DEFAU

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

SELECT * 
FROM doctors
WHERE unaccent_t(fullname) ~* 'unaccented_and_lowercase_string';
其中要搜索的值为uncented+小写,uncent是一个定义为:

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;
(我已经安装了“uncent”扩展)

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

(我也试过使用varchar_pattern_ops,也没有指定ops)

在医生表中,我有大约1.5万行

查询工作正常,我得到了预期的结果,但当我将
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
我还尝试从uncent\t中删除可选参数,但得到了相同的结果


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

b只有在模式保持锚定状态时,树索引才可用于加速操作

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


您可以在PostgreSQL手册的

上阅读更多关于它的内容。这种技术可以与
=
或左锚定的类似项一起使用,但是
~*
是一个匹配正则表达式的运算符。因此,只需尝试
选择*应该使用索引的名称,如“%garcia”
。但这不会
选择*WHERE name像'garcia%'
谢谢,听起来不错。然后,我将为这种类型的搜索创建一个gin/gist索引。干杯。尝试使用
\u text\u ops
创建gin索引时,告诉我此运算符不接受文本数据。没有指定任何选项,它告诉我没有默认的操作符类。指定
gin\u trgm\u ops
将创建索引,它可以工作,但我不会在该字段中执行“trigram”全文搜索。是否有其他运算符类可用于此gin索引?或者使用
gin\u trgm\u ops
也可以,即使我不执行任何全文搜索?此外,解释分析现在告诉我正在使用索引,但不使用索引时执行时间基本相同。这就像索引没有改善查询的执行时间一样。可能有什么问题?GIN或GIST\u trgm\u ops索引可用于加速任何regexp或类似搜索。如果生成的执行时间与没有索引的执行时间相似,可能是因为您的数据集很小,或者您选择的数据很大一部分。mnencia,这很有意义。我的测试数据和你提到的一样。好的是,现在我知道索引正在被使用。因此,在我的查询场景中,这个gin索引将完成这项工作。再次感谢。
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