假设从理论上讲,我的数据库具有荒谬的表数(100,000+)。这会导致任何类型的性能问题吗?假设大多数查询 (99%+) 一次只能在 2-3 个表上运行。
因此,我的问题是:
PostgreSQL 中表数的 O(n) 操作是什么?
请注意,没有关于这是多么糟糕的设计的答案,或者我需要如何计划更多关于我正在设计的内容。假设对于我的情况,拥有大量表是最好的设计。
假设从理论上讲,我的数据库具有荒谬的表数(100,000+)。这会导致任何类型的性能问题吗?假设大多数查询 (99%+) 一次只能在 2-3 个表上运行。
因此,我的问题是:
PostgreSQL 中表数的 O(n) 操作是什么?
请注意,没有关于这是多么糟糕的设计的答案,或者我需要如何计划更多关于我正在设计的内容。假设对于我的情况,拥有大量表是最好的设计。
pg_dump并且实际上比这更糟,是O(N ^ 2)pg_restore。pg_upgrade这曾经是一个大问题,尽管在最近的版本中,N^2 的常数已经降低到如此之低,以至于对于 100,000 个表来说,这可能不足以成为您最大的问题。然而,还有更糟糕的情况,比如每个表的转储表可能是 O(M^2) (可能是 M^3,我不记得确切的细节了),其中 M 是表中的列数。这仅适用于列具有检查约束或默认值或名称和类型之外的其他附加信息时。当您没有警告您的操作问题,但突然发现您无法在合理的时间范围内升级时,所有这些问题都特别令人讨厌。
一些物理备份方式,比如barmanusing rsync,在文件数量上也是 O(N^2) ,至少和表的数量一样多。
在正常操作期间,统计信息收集器可能是一个很大的瓶颈。每次有人请求更新某个表的统计信息时,它都必须写出一个覆盖该数据库中所有表的文件。对于该数据库中的表来说,写出来是 O(N)。(过去更糟糕的是,为 while 实例写出一个文件,而不仅仅是数据库)。这在某些文件系统上可能会变得更糟,当在现有文件的顶部重命名一个文件时,会隐式地对文件进行 fsync,因此将其放在 RAM 磁盘上至少可以改善这种情况。
autovacuum worker 循环遍历每个表(大约每个 autovacuum_naptime 一次)来决定是否需要清理它们,因此大量表可以减慢速度。这也可能比 O(N) 更糟,因为对于每个表,它都可能会请求更新的统计信息。更糟糕的是,这样做可能会阻止所有并发的 autovacuum 工作人员(最后一部分已在所有受支持版本的补丁中修复)。
您可能遇到的另一个问题是,每个数据库后端都在其生命周期内访问的每个表(或其他对象)上维护元数据缓存。没有使此缓存过期的机制,因此如果每个连接都涉及大量表,它将开始消耗大量内存,并且每个后端都有一个副本,因为它不是共享的。如果您有一个无限期地保持连接打开的连接池,这真的可以加起来,因为每个连接的寿命足够长以接触许多表。
pg_dump有一些选择,可能-s。其他一些选项使其更多地取决于数据的大小。