2015-12-11 22 views
0

我想知道在非常大的PosgreSQL中使用非顺序的UUID作为主键的性能影响。Postgres中的UUID主键,插入性能影响?

在对表记录使用集群存储的DBMS中,给定使用UUID会增加插入的成本,因为必须从磁盘读取数据以找到插入的数据页面,表太大而无法保存在内存中。据我了解,Postgres不会在插入时维护行集群,所以我想像在Postgres中使用UUID PK不会影响插入的性能。

但是我认为它会使插入到索引中的主键约束创建的代价大得多,因为它必须不断地从磁盘读取以更新插入新数据时的索引。而使用顺序键索引只会在内存中的提示处更新。

假设我正确理解对索引的性能影响,是否有任何方法可以解决这个问题,或者是UUID在大的未分区表上简直不是一个好PK?

回答

2

据我了解,Postgres并没有保持在插入

正确的时刻排集群。不幸。

所以我想在Postgres中使用UUID PK不会损害插入的性能。

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

  • UUID是宽4次为一个典型的32位整数合成关键,所以写行是12个字节更大,可以适合更少的行成的RAM

  • 一个给定的量实现主键的b-tree索引将是4倍大(而不是32位键),搜索需要更长的时间并需要更多内存来缓存。它也需要更频繁的页面拆分。

  • 写操作将趋于索引中随机的,不附加热,最近访问的行

有没有什么办法补救[上的索引性能影响]或者是UUID的根本在一个大的,未分区的桌子上的好PK?

如果你需要一个UUID键,你需要一个UUID键。如果你不需要一个,你就不应该使用它,但是如果你不能使用合成键的核心来源,并且没有合适的自然键可以使用,它仍然是一条路。

除非您可以将写入限制在一个分区上,否则分区将不会有多大帮助。此外,如果一次只写入一个分区,您将无法在搜索关键字时有效地使用约束排除,因此在进行查询时,您仍然必须搜索所有分区的索引。我只能看到它是有用的,如果你的UUID是组合键的一部分,你可以在组合键的另一部分进行分区。

+0

为什么PostgreSQL不存储数据集群是“不幸”?我从来没有理解为什么这是存储关系表的_default_方法。有些情况下,它是有用的,但作为一般默认,我不买它。但是,也许我一直在Oracle工作太久,索引组织表(Oracle相当于聚集索引)是例外情况。 –

+0

我不认为它应该是默认值;堆通常具有更好的属性。但是索引组织的表格非常适合大部分阅读的表格。这是一个痛苦的'CLUSTER'一直在桌子上。您仍然可以创建大型索引以用于仅索引扫描,但这是对磁盘和I/O的浪费。 PostgreSQL帮助中的HOT更新,尽管需要每个页面中用于写入更新元组的浪费空间。 BRIN索引将从试图指导写入接近相似值的尝试中受益匪浅,并且希望还可以使实现这种功能变得更加容易。 –