为什么分区 table 大小大于具有相同数据的正常 table 大小

Why a partitioned table size is larger than a normal table size with the same data

我把相同的数据插入到两个table中:一个是分区的,一个是正常的。 我用下面的命令来确定正常大小 table:

select pg_size_pretty (pg_total_relation_size ('test_normal'))

输出为:6512 MB

我使用以下命令来确定分区的大小 table:

select sum(to_number(pg_size_pretty(pg_total_relation_size(inhrelid::regclass)),'999999999')) from pg_inherits where inhparent = 'test_partition'::regclass

输出为:6712.1 MB

分区table有1001个分区。 两个 table 都没有索引或约束。

如果空分区的大小为 0 字节,为什么两个 table 之间存在如此大的差异 (200 MB)?

主要问题是你调用to_number(pg_size_pretty(...),'999999999')pg_size_pretty returns 类似123 MB123 GB 的值,两者都会变成123,所以总和是错误的。即使所有单位恰好相同,您仍然会出现舍入误差。

所以在 求和尺寸后调用 to_number

未分区的 table 和分区的 table 之间当然可能仍然存在小差异。

非常感谢劳伦斯

我搜索了另一种方法来确定分区 table 的大小,我发现了这个 post:

所以我试试这个:

WITH RECURSIVE tables AS (
 SELECT
   c.oid AS parent,
   c.oid AS relid,
   1     AS level
 FROM pg_catalog.pg_class c
 LEFT JOIN pg_catalog.pg_inherits AS i ON c.oid = i.inhrelid
   -- p = partitioned table, r = normal table
 WHERE c.relkind IN ('p')
   -- not having a parent table -> we only get the partition heads
   AND i.inhrelid IS NULL
 UNION ALL
 SELECT
   p.parent         AS parent,
   c.oid            AS relid,
   p.level + 1      AS level
 FROM tables AS p
 LEFT JOIN pg_catalog.pg_inherits AS i ON p.relid = i.inhparent
 LEFT JOIN pg_catalog.pg_class AS c ON c.oid = i.inhrelid AND c.relispartition
 WHERE c.oid IS NOT NULL
)
SELECT
 parent ::REGCLASS                                  AS table_name,
 pg_size_pretty(sum(pg_total_relation_size(relid))) AS pretty_total_size,
 sum(pg_total_relation_size(relid))                 AS total_size
FROM tables
GROUP BY parent
ORDER BY sum(pg_total_relation_size(relid)) DESC

结果现在更有意义了!