我想知道在PosgreSQL中使用非顺序UUID作为表中主键的性能影响。
在使用集群存储进行表记录的DBMS中,由于必须从磁盘读取以查找要执行插入的数据页,因此使用UUID会增加插入成本,一旦桌子太大,无法容纳在记忆中。据我了解,Postgres不会在插入上维护行聚类,所以我想在Postgres中使用UUID PK不会损害该插入的性能。
但我认为它会使插入到索引中的主键约束在表很大时会产生更高的成本,因为它必须不断地从磁盘读取以在插入新数据时更新索引。而使用顺序键,索引只会在尖端更新,而尖端始终在内存中。
假设我正确理解了对索引的性能影响,有没有办法解决这个问题,或者UUID在大型未分区表上是不是一个好的PK?
答案 0 :(得分:14)
据我了解,Postgres不会在插入上维护行聚类
此刻正确。不幸的是
所以我想在Postgres中使用UUID PK并不会影响该插入的性能。
由于需要维护PK,并且因为插入的元组更大,它仍然具有性能成本。
uuid是典型的32位整数合成密钥的4倍宽,因此要写入的行大12个字节,您可以将更少的行放入给定的RAM量
实现主键的b-tree索引将是4x(与32位密钥相比),搜索时间更长,需要更多内存来缓存。它还需要更频繁的页面拆分。
写入在索引中往往是随机的,不会附加到热门的,最近访问过的行
有没有办法解决[对索引的性能影响],或者UUID在大型未分区的表上不是一个好的PK?
如果您需要UUID密钥,则需要UUID密钥。如果你不需要,你不应该使用一个,但如果你不能依赖合成键的中心来源并且没有合适的自然键可供使用,那么它仍然是要走的路。
除非您可以将写入限制在一个分区,否则分区不会有太大帮助。此外,如果一次仅写入一个分区,您将无法在搜索密钥时使用约束排除功能,因此您仍然需要搜索所有分区'执行查询时键的索引。我只能看到它是有用的,如果你的UUID构成复合键的一部分,你可以在复合键的另一部分上进行分区。
答案 1 :(得分:1)
应该指出的是,如果启用了full_page_writes
选项的UUID列上的btree索引将产生更多的WAL。发生这种情况是由于UUID随机性-值不是连续的,因此每个插入都可能会接触到全新的叶子索引叶子页面。您可以在On the impact of full-page writes文章中阅读更多内容。