Postgresql
text_pattern_ops 和 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")
這些方法是完全等效的還是有區別的?
請注意,如果您希望涉及普通
<
、<=
、>
或>=
比較的查詢使用索引,則還應該使用預設運算符類創建索引。此類查詢不能使用xxx_pattern_ops
運算符類。(但是,普通的相等比較可以使用這些運算符類。)可以使用不同的運算符類在同一列上創建多個索引。如果確實使用 C 語言環境,則不需要xxx_pattern_ops
運算符類,因為具有預設運算符類的索引可用於 C 語言環境中的模式匹配查詢。因此,索引可以
COLLATE "C"
做所有text_pattern_ops
事情,加上後者不能做的事情。喜歡支持這個查詢:SELECT * FROM t WHERE name >= 'z' COLLATE "C";
COLLATE "C"
必須在查詢中明確指定以使COLLATE "C"
索引適用(除非您以“C”排序規則開頭,但為什麼要索引?)上面的查詢需要“每列排序支持”的特性(就像你的索引一樣)。該功能是在 Postgres 9.1 中添加的。在 Postgres 9.1 之前,操作符類
text_pattern_ops
更古老並且很有意義。從 Postgres 9.1 開始,COLLATE “C” 變體更出色,因為它更通用。我能想到的唯一原因是出於某種奇怪的原因故意不支持其他案例。該手冊實際上可能會為操作員類添加棄用通知
xxx_pattern_ops
。