text_pattern_ops 和 COLLATE "C" 之间有区别吗?

And*_*eKR 3 postgresql index collation

name例如,如果我有一个带有排序规则的文本列tr-TR,并且我运行一个查询

SELECT * FROM t WHERE name LIKE 'a%'
Run Code Online (Sandbox Code Playgroud)

然后这将进行 seq 扫描。

如果我现在创建一个索引

CREATE INDEX ON t(name text_pattern_ops)
Run Code Online (Sandbox Code Playgroud)

上面的查询将变成位图扫描。但还有另一种技术可以达到相同的结果:

CREATE INDEX ON t(name COLLATE "C")
Run Code Online (Sandbox Code Playgroud)

这些方法完全等同还是存在差异?

Erw*_*ter 6

手册:

<请注意,如果您希望涉及普通、<=>>= 比较的查询使用索引,您还应该使用默认运算符类创建索引。此类查询不能使用 xxx_pattern_ops运算符类。(但是,普通的相等比较可以使用这些运算符类。)可以使用不同的运算符类在同一列上创建多个索引。如果您确实使用 C 语言环境,则不需要xxx_pattern_ops 运算符类,因为具有默认运算符类的索引可用于 C 语言环境中的模式匹配查询。

因此,索引 with可以COLLATE "C"完成a可以做的所有事情text_pattern_ops,还可以做更多后者不能做的事情。喜欢支持这个查询:

SELECT * FROM t
WHERE name >= 'z' COLLATE "C";
Run Code Online (Sandbox Code Playgroud)

COLLATE "C"必须在查询中显式指定才能使COLLATE "C"索引适用(除非您一开始就使用“C”排序规则进行操作,但为什么要使用索引呢?)

上面的查询需要“每列排序规则支持”的功能(就像您的索引一样)。该功能是在 Postgres 9.1 中添加的。运算符类text_pattern_ops要古老得多,并且在 Postgres 9.1 之前就很有意义。

从 Postgres 9.1 开始,COLLATE“C”变体更加优越,因为它更通用。我能想到的唯一原因是出于某种奇怪的原因故意支持其他用例。该手册实际上可能会添加运算符类的弃用通知xxx_pattern_ops