【发布时间】:2016-09-29 11:49:23
【问题描述】:
我有一个仅包含 ASCII 符号的 varchar 列。我不需要按此字段排序,但我需要按完全相等来搜索它。
默认语言环境是en.UTF8。如果我用collate "C" 创建这个专栏,我会得到什么吗?
【问题讨论】:
标签: postgresql database-design locale
我有一个仅包含 ASCII 符号的 varchar 列。我不需要按此字段排序,但我需要按完全相等来搜索它。
默认语言环境是en.UTF8。如果我用collate "C" 创建这个专栏,我会得到什么吗?
【问题讨论】:
标签: postgresql database-design locale
是的,这很重要。
即使您不刻意排序,内部也有各种操作需要排序步骤(一些聚合函数、DISTINCT、嵌套循环连接等)。
此外,字段上的任何 index 都必须在内部对值进行排序 - 并遵守排序规则,除非 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语言环境是安全的,因为它既不使用strcoll()也不使用strxfrm()。)不幸的是,这个问题不仅会影响排序,还会影响条目 在 B-tree 索引中排序,这意味着
text上的 B-tree 索引,varchar或char列现在可能已损坏,如果它们根据 受影响的语言环境,并且是在 PostgreSQL 9.5.0 下构建或修改的 或 9.5.1。用户应REINDEX可能受到影响的索引。目前无法提供详尽的清单 已知受影响的语言环境。
C语言环境已知安全,并且没有 在英语语言环境中存在问题的证据,例如en_US,但有些 其他流行的语言环境,例如de_DE在大多数 glibc 中都会受到影响 版本。
这个问题还说明了排序规则的来源。
【讨论】: