Postgres中的UUID主键,什么插入性能影响?

phi*_*est 23 database postgresql indexing performance uuid

我想知道在PosgreSQL中使用非顺序UUID作为表中主键的性能影响.

在使用集群存储来存储表记录的DBMS中,一旦表太大,使用UUID会增加插入成本,因为必须从磁盘读取以查找要执行插入的数据页.留在记忆中.据我了解,Postgres不会在插入上维护行聚类,所以我想在Postgres中使用UUID PK不会损害该插入的性能.

但我认为它会使插入到索引中的主键约束一旦表很大就会变得更加昂贵,因为它必须不断地从磁盘读取以在插入新数据时更新索引.而使用顺序键,索引只会在尖端更新,而尖端始终在内存中.

假设我正确理解了对索引的性能影响,有没有办法解决这个问题,或者UUID在一个大的,未分区的表上是不是一个好的PK?

Cra*_*ger 19

据我了解,Postgres不会在插入上维护行聚类

此刻正确.不幸.

所以我想在Postgres中使用UUID PK并不会损害该插件的性能.

它仍然具有性能成本,因为需要维护PK,并且因为插入的元组更大.

  • uuid是典型的32位整数合成密钥的4倍宽,因此要写入的行大12个字节,您可以将更少的行放入给定数量的RAM中

  • 实现主键的b-tree索引将是4x(与32位密钥相比),搜索时间更长,需要更多内存来缓存.它还需要更频繁的页面拆分.

  • 写入在索引中往往是随机的,不会附加到最近访问的热门行

有没有办法解决[对索引的性能影响]或者UUID在一个大的,未分区的表上是不是一个好的PK?

如果需要UUID密钥,则需要UUID密钥.如果你不需要一个,你不应该使用一个,但如果你不能依赖合成键的中心来源,并且没有合适的自然键可以使用,它仍然是要走的路.

除非您可以将写入限制在一个分区,否则分区将无济于事.此外,如果一次仅写入一个分区,则无法在搜索密钥时使用约束排除,因此在执行查询时,您仍需要搜索所有分区的索引以查找密钥.我只能看到它是有用的,如果你的UUID构成复合键的一部分,你可以在复合键的另一部分上进行分区.

  • 为什么Postgres不存储集群数据是“不幸的”?我从未理解过为什么这将是存储关系表的_default_方法。在某些情况下,它很有帮助,但作为一般默认设置,我不购买。但是也许我在Oracle上工作了太长时间了,那里的索引组织表(Oracle等效于聚集索引)是例外。 (2认同)
  • 我不认为它应该是默认值;堆通常具有更好的属性。但是索引组织的表非常适用于大量联接的以读取为主的表。一直在一张桌子上“集群”很痛苦。您仍然可以创建大的胖索引以用于仅索引扫描,但这会浪费磁盘和 I/O。PostgreSQL 中的 HOT 更新提供了帮助,尽管代价是需要浪费每个页面中的空间来用于编写更新的元组。BRIN 索引将从尝试在相似值附近直接写入中受益匪浅,并且有望使实现此类功能更容易。 (2认同)

pen*_*rik 5

应该提到的是,如果您在full_page_writes启用选项的UUID 列上有 btree 索引,您将获得更多的 WAL 。发生这种情况是因为 UUID 随机性 - 值不是连续的,因此每个插入都可能触及全新的叶索引叶页。您可以在关于整页写作的影响文章中阅读更多内容。