2

考虑:

create table tab (foo text not null);
create index tab_ix_foo on tab(foo);

select * from tab where foo like 'pre%';

Postgres 不使用索引来进行搜索。使用排序规则"POSIX"时,Postgres 使用索引:http ://sqlfiddle.com/#!12/ed1cc/1

使用排序规则"en_US"时,Postgres 使用顺序扫描:http ://sqlfiddle.com/#!12/efb18/1

为什么有区别?

4

1 回答 1

4

C当使用(ie )以外的语言环境时,POSIX您需要使用opclass为文本搜索创建索引LIKE和前缀。请参阅有关Operator classesindex types的文档。我确信有比那个文档页面更好的参考,但我现在似乎找不到它。~text_pattern_ops

如果我更改您的 SQLFiddle 以text_pattern_ops用于en_US索引,您会看到它能够使用索引

create index tab_ix_foo on tab using btree (foo collate "en_US" text_pattern_ops);
--                                                              ^^^^^^^^^^^^^^^^

如果您在 9.2+ 中使用该选项,您很可能需要为不同的排序规则创建不同的索引COLLATE,因为根据定义,不同的排序规则几乎意味着字符串的不同顺序,因此也意味着不同的 b-tree 组织。看来您已经在测试中这样做了。

也有可能您的数据太小而无法使用索引来特别有用。尝试使用更有用的数据量进行测试。

这篇文章可能很有用,排序规则支持上的文档也可能有用。


为什么不能只对不同的排序规则使用相同的 b-tree 索引,请考虑 b-trees 需要稳定且一致的排序,但是:

regress=> SELECT ' Bill''s' > ('bills' COLLATE "POSIX");
 ?column? 
----------
 f
(1 row)

regress=> SELECT ' Bill''s' > ('bills' COLLATE "en_US");
 ?column? 
----------
 t
(1 row)

如您所见,排序规则更改了排序顺序。这就是排序规则所做的,几乎按照定义。尝试对不同的排序规则使用相同的索引就像尝试对不同的函数使用相同的功能索引;这完全没有意义。

于 2013-03-24T11:16:06.467 回答