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