我想知道使用非顺序UUID作为表中的主键会对性能产生什么影响,在PosgreSQL中,这个表将变得非常大.

在对表记录使用集群存储的DBMS中,一旦表太大而无法保存在内存中,使用UUID将增加插入的成本,因为必须从磁盘读取数据页才能执行插入.据我所知,Postgres不会在insert上维护行集群,因此我认为在Postgres中使用UUID PK不会影响该insert的性能.

但是我认为,一旦表很大,它会使PRIMARY KEY约束创建的对索引的INSERT代价更高,因为在插入新数据时必须不断地从磁盘读取以更新索引.而使用顺序键时,索引将仅在提示处更新,该提示将始终在内存中.

假设我正确理解了对索引的性能影响,有什么方法可以解决这个问题吗?或者UUID根本不是一个大型的、未分区的表上的好PK吗?

推荐答案

据我所知,Postgres不维护插入上的行聚类

目前是正确的.不幸的是.

因此,我认为在Postgres中使用UUID PK不会影响插入的性能.

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

  • UUID的宽度是典型的32位整数合成键的4倍,因此要写入的行长12个字节,在给定的RAM容量中可以容纳更少的行

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

  • 在索引内写入往往是随机的,而不是追加到最近访问的热门行

有没有办法补救[对索引的性能影响],或者UUID根本不是一个大型的、未分区的表的好PK?

如果需要UUID密钥,则需要UUID密钥.如果你不需要合成键,你就不应该使用,但是如果你不能依赖合成键的中央来源,并且没有合适的自然键可以使用,那么它仍然是可行的.

分区不会有多大帮助,除非您可以将写入限制在一个分区内.此外,如果一次只写入一个分区,则在搜索键时将不能有效地使用约束排除,因此在执行查询时仍必须在所有分区的索引中搜索键.我认为只有当您的UUID形成组合键的一部分,并且您可以在组合键的另一部分上进行分区时,它才有用.

Database相关问答推荐

在多组MongoDB中查找最新文档的有效方法

postgres 索引扫描的启动成本(postgresql 书的内部 struct )

我们可以出于不同目的在同一 postgres 数据库上同时进行物理和逻辑复制吗?

如何在华为Appcube中创建和使用对象(模型)?

我如何知道 DynamoDB 表分布在多少个分区上?

如何将 Grails 3.0 连接到我的本地 Mysql 数据库

创建数据库索引有哪些最佳实践和经验法则?

在sql server中拆分字符串

如何手动卸载 Oracle?

数据库设计:多表与单表

估计数据库大小

SQL Server 中的Is Identity列属性是什么意思?

PostgreSQL - 按时间戳值分组?

按请求的可变事务隔离级别

数据库内部—从哪里开始?

在 MySQL 中实现一对一关系时确定外键

JavaScript 布尔搜索查询生成器接口库?

MongoDB中的数据库数据大小

Codeigniter - 使用多个数据库

使用 Sinatra 时与数据库对话的最佳方式是什么?