我有一个名为"doctors"的表,里面有一个名为"fullname"的字段,用于存储带有重音符号的姓名。
我需要进行“忽略重音符号+大小写不敏感”的搜索,例如:
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”扩展。
因此,我继续为“fullname”字段创建了索引:
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,但~*
是用于匹配正则表达式的运算符。 - Daniel VéritéSELECT * WHERE name like '%garcia'
,这应该使用索引。但是这个不会:SELECT * WHERE name like 'garcia%'
。 - Juan Carlos Oropeza