@H_
403_0@
我有一个遗留架构(免责声明!),它为所有表的主键使用基于散列的
生成id(有很多).这种id的一个例子是:
922475bb-ad93-43ee-9487-d2671b886479
改变这种方法是没有希望的,但是索引访问的性能很差.撇开这可能有多种原因,有一件事我注意到它似乎不是最优的 – 尽管所有多个表中的所有id值都是36个字符长,但列类型是varchar(36),而不是char(36) ).
将列类型更改为固定长度char(36)是否会提供任何显着的索引性能优势,除了每个索引页面的条目数量的极小增加等?
即使处理固定长度类型而不是可变长度类型,postgres的执行速度要快得多吗?
请不要提到微小的存储节省 – 与更改柱子所需的手术相比,这并不重要.
没有.根本没有收益.
The manual explicitly states:
Tip: There is no performance difference among these three types,apart
from increased storage space when using the blank-padded type,and a
few extra cpu cycles to check the length when storing into a
length-constrained column. While character(n)
has performance
advantages in some other database systems,there is no such advantage
in Postgresql; in fact character(n)
is usually the slowest of the
three because of its additional storage costs. In most situations text
or character varying
should be used instead.
大胆强调我的.
char(n)是一种基本上过时的,无用的类型.坚持varchar(n).如果您不需要强制执行长度,则varchar或text会更快一点.
你将无法衡量差异.
此外,如果所有字符串的长度恰好为36个字符,则无论如何都不会保存存储空间,即使是非常小的存储空间也是如此.两者在磁盘和RAM中的大小完全相同.您可以使用pg_column_size()
进行测试(在表达式和表格列上).
有关:
> Any downsides of using data type “text” for storing strings?
你没有要求其他选择,但我会提到两个:
> COLLATION
– 除非您使用“C” collation运行数据库.整理经常被忽视并且可能很昂贵.由于您的字符串在自然语言中似乎没有意义,因此遵循COLLATION规则可能没有意义.有关:
> How do I efficiently get “the most recent corresponding row”?
> EXECUTE within function not using index?
广泛的基准比较(以及其他)COLLATE“C”对性能的影响:
> Slow query ordering by a column in a joined table
> UUID,显然.您的字符串可疑地看起来像UUID(32位十六进制数字加上4个分隔符).将这些作为实际的uuid数据类型存储会更加有效,它在多种方式下更快并且仅占用16个字节 – 而在RAM(37)或varchar(36)中存储37个字节(存储没有分隔符,只是32个定义的char),或磁盘上的33个字节.但在许多情况下,alignment padding将导致40字节.)COLLATION也与uuid数据类型无关.
SELECT '922475bb-ad93-43ee-9487-d2671b886479'::uuid
这可能会有所帮助(最后几章):
> Convert hex in text representation to decimal number
也可以看看:
> What is the overhead for varchar(n)?
> What is the optimal data type for an MD5 field?