Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Postgresql 在citext表达式上使用索引的类似搜索_Postgresql_Indexing_Expression - Fatal编程技术网

Postgresql 在citext表达式上使用索引的类似搜索

Postgresql 在citext表达式上使用索引的类似搜索,postgresql,indexing,expression,Postgresql,Indexing,Expression,背景: --Postgres在RDS上的成绩为11.4,在macOS上的成绩为11.5。 --记录更改日志详细信息表在我的测试设置中大约有8M。 --旧值字段的类型为citext。 --字段中的值的长度范围从1个字符到超过5000个字符。大多数都很短 据我所知,我需要在这里使用表达式索引,因为我的一些值对于B树条目来说太长了。根据Postgres 11发行说明: “允许创建可供citext列上类似比较使用的索引(Alexey Chernyshov) 为此,必须使用citext_pattern_o

背景: --Postgres在RDS上的成绩为11.4,在macOS上的成绩为11.5。 --记录更改日志详细信息表在我的测试设置中大约有8M。 --旧值字段的类型为citext。 --字段中的值的长度范围从1个字符到超过5000个字符。大多数都很短

据我所知,我需要在这里使用表达式索引,因为我的一些值对于B树条目来说太长了。根据Postgres 11发行说明:

“允许创建可供citext列上类似比较使用的索引(Alexey Chernyshov) 为此,必须使用citext_pattern_ops操作符类创建索引。”

下面是我的示例数据的索引定义:

CREATE INDEX record_changes_log_detail_old_value_ix_btree
    ON record_changes_log_detail 
    USING btree ((substring(old_value,1,1024)::citext) citext_pattern_ops);
如果运行此查询分析,我可以看到使用了索引:

因此,=搜索正如所希望的那样工作。但是,此查询不使用索引:

select * from record_changes_log_detail where substring(old_value,1,1024)::citext LIKE 'Gold Kerrison Neuro%';
是否有一些技巧可以让citext索引处理我错过的类似查询,或者这更可能是一个bug?作为比较,如果使用文本模式构建LIKE查询,那么LIKE查询不会使用索引。但是,当然,它是区分大小写的

区分大小写 下面是关于案例敏感性的评论。我认为“pg_trgm”是不分大小写的,但没有时间进行彻底的审查。作为一个快速检查,这三个比较都返回1,这是一个完美的匹配

select similarity('hello world','hello world');
select similarity('hello world','HELLO WORLD');
select similarity('Hello World','hello world');

我就这个问题向PG bugs邮件列表发送了一条消息,并从Tom Lane那里得到了答复。我对答案的总结是“这是一个文档错误”。citext_模式不支持类似的查询

为了档案,我想我应该把这些信息贴在这里

根据Laurenz Albe的建议,我尝试了Postgres tri-gram的实现。他们统治

DROP INDEX IF EXISTS record_changes_log_detail_old_value_ix_tgrm;
CREATE INDEX record_changes_log_detail_old_value_ix_tgrm
    ON record_changes_log_detail 
    USING gin (old_value gin_trgm_ops);
当您使用citext时,这里的秘密是将您的值强制转换为::text,如下所示:

select * from record_changes_log_detail 
where old_value::text LIKE '%Gold Kerrison Neuro%';

使用explain ANALYSE运行该分析,以确认是否使用了索引。

我没有答案,但我怀疑您看到的行为与您使用的是功能索引有关,而不是与
citext
有关。此外,也许你想在问另一个非常类似的问题之前等待答案。公正的评论。而且,是的,我正在努力问一些问题,这些问题足够简短,但有足够的细节…足够狭窄和清晰,但不太重叠。我是新来的SO,我试着做一些适当的事情。事情进展不顺利;-)关于功能部分,我已经更新了我的答案。我用了很多方法对此进行了测试,当您使用文本操作而不是citext操作构建时,索引用于LIKE。一种解决方法是只维护
旧值
列的小写列版本。然后,只需添加一个常规的BTree索引,
LIKE
应该可以使用它。但是将字段转换为文本会使LIKE区分大小写。我已经更新了我的问题,快速回答了这个评论。
select * from record_changes_log_detail 
where old_value::text LIKE '%Gold Kerrison Neuro%';