例如,如果我有一个name
带有排序规则的文本列tr-TR
,并且我运行一个查询
SELECT * FROM t WHERE name LIKE 'a%'
然后这将进行 seq 扫描。
如果我现在创建一个索引
CREATE INDEX ON t(name text_pattern_ops)
上面的查询会变成位图扫描。但是还有另一种技术可以达到相同的结果:
CREATE INDEX ON t(name COLLATE "C")
这些方法是完全等效的还是有区别的?
例如,如果我有一个name
带有排序规则的文本列tr-TR
,并且我运行一个查询
SELECT * FROM t WHERE name LIKE 'a%'
然后这将进行 seq 扫描。
如果我现在创建一个索引
CREATE INDEX ON t(name text_pattern_ops)
上面的查询会变成位图扫描。但是还有另一种技术可以达到相同的结果:
CREATE INDEX ON t(name COLLATE "C")
这些方法是完全等效的还是有区别的?
手册:
因此,索引可以
COLLATE "C"
做所有text_pattern_ops
事情,加上后者不能做的事情。喜欢支持这个查询:COLLATE "C"
必须在查询中明确指定以使COLLATE "C"
索引适用(除非您以“C”排序规则开头,但为什么要索引?)上面的查询需要“每列排序支持”的特性(就像你的索引一样)。该功能是在 Postgres 9.1 中添加的。在 Postgres 9.1 之前,操作符类
text_pattern_ops
更古老并且很有意义。从 Postgres 9.1 开始,COLLATE "C" 变体更出色,因为它更通用。我能想到的唯一原因是出于某种奇怪的原因故意不支持其他用例。该手册实际上可能会为操作员类添加弃用通知
xxx_pattern_ops
。好吧,查询可以使用 atext_pattern_ops
而无需COLLATE "C"
在正确的位置添加。