我有一个varchar
列,只包含ASCII符号。我不需要按此字段排序,但我需要完全平等地搜索它。
默认语言区域为en.UTF8
。如果我使用collate "C"
创建此列,我会获得任何收益吗?
答案 0 :(得分:0)
是,它会有所作为。
即使您没有刻意排序,也有各种操作需要内部排序步骤(一些聚合函数,DISTINCT
,嵌套循环连接等。)。
此外,字段上的任何索引都必须在内部对值进行排序 - 并遵守排序规则,除非适用COLLATE "C"
(无排序规则)。
对于完全相等的搜索,你需要一个索引 - 它可以以任何方式工作(为了相等),但是如果没有整理规则,它会更快。根据您的使用案例的细节,效果可以忽略不计或大幅度。影响随着字符串的长度而增长。我前段时间对相关案例进行了基准测试:
此外,还有更多模式匹配选项与区域设置“C”。另一种方法是使用特殊的varchar_pattern_ops
运算符类创建索引。
相关:
Postgres 9.5 通过一种名为“缩写键”的技术引入了性能改进,这种技术在某些语言环境中遇到了问题。所以除了C
语言环境之外,它已被停用。 Quoting The release notes of Postgres 9.5.2:
- 在非
C
语言环境中禁用字符串排序的缩位键(Robert Haas)PostgreSQL 9.5引入了加速字符串比较的逻辑 使用标准C库函数
strxfrm()
作为数据类型 替换strcoll()
。它现在出现了glibc的大多数版本 (Linux的C库实现)有错误的实现 在strxfrm()
中,在某些语言环境中,可以生成字符串比较 结果与strcoll()
不符。直到这个问题可以更好 表征,禁用所有非C语言环境中的优化。 (C
locale是安全的,因为它既不使用strcoll()
也不使用strxfrm()
。)不幸的是,这个问题不仅会影响排序,还会影响输入 在B树索引中排序,这意味着
text
上的B树索引,varchar
或char
列如果按照排序排序可能会损坏 受影响的区域设置,并在PostgreSQL 9.5.0下构建或修改 或9.5.1。用户应REINDEX
可能受影响的索引。目前无法提供详尽的清单 已知受影响的区域设置。
C
语言环境是安全的,没有 在en_US
等基于英语的语言环境中出现问题的证据,但有些问题 其他流行的语言环境如de_DE
在大多数glibc中受到影响 版本
问题还说明了整理规则的来源。