Postgresql 获取分区表的表大小(Postgres 10+;)
我遇到了这个查询,其中以字节为单位显示了表、表大小、toast大小和索引大小:Postgresql 获取分区表的表大小(Postgres 10+;),postgresql,postgresql-10,postgresql-11,Postgresql,Postgresql 10,Postgresql 11,我遇到了这个查询,其中以字节为单位显示了表、表大小、toast大小和索引大小: SELECT relname AS table_name, pg_size_pretty(pg_total_relation_size(relid)) AS total, pg_size_pretty(pg_relation_size(relid)) AS internal, pg_size_pretty(pg_table_size(relid) - pg_relation_size(relid))
SELECT
relname AS table_name,
pg_size_pretty(pg_total_relation_size(relid)) AS total,
pg_size_pretty(pg_relation_size(relid)) AS internal,
pg_size_pretty(pg_table_size(relid) - pg_relation_size(relid)) AS external,
pg_size_pretty(pg_indexes_size(relid)) AS indexes
FROM pg_catalog.pg_statio_user_tables
ORDER BY pg_total_relation_size(relid) DESC;
我知道Postgres正在为每个分区创建一个表,因此我将分别为每个分区获取条目,但是否有方法可以为每个表获取一行,而不管该表是否已分区?当然,但您必须与一组其他目录表合并,并使用
GROUP BY
- 目录
中的属性pg_class
将告诉您一个关系是分区的(relkind
),还是不分区的(p
)r
- 目录
将告诉您哪个分区(pg_inherits
)属于哪个分区表(inhrelid
)inhparent
由于分区可以再次分区,如果您想覆盖所有的基,就必须编写一个递归公共表表达式。按照@Laurenz的指示,尽管我创建了一个满足需要的查询。这将获得特定数据库中所有分区表的总内存
SELECT
pi.inhparent::regclass AS parent_table_name,
pg_size_pretty(sum(pg_total_relation_size(psu.relid))) AS total,
pg_size_pretty(sum(pg_relation_size(psu.relid))) AS internal,
pg_size_pretty(sum(pg_table_size(psu.relid) - pg_relation_size(psu.relid))) AS external, -- toast
pg_size_pretty(sum(pg_indexes_size(psu.relid))) AS indexes
FROM pg_catalog.pg_statio_user_tables psu
JOIN pg_class pc ON psu.relname = pc.relname
JOIN pg_database pd ON pc.relowner = pd.datdba
JOIN pg_inherits pi ON pi.inhrelid = pc.oid
WHERE pd.datname = :database_name
GROUP BY pi.inhparent
ORDER BY sum(pg_total_relation_size(psu.relid)) DESC;
请注意,在分区的情况下,根表不会有一行,但每个父表都有自己的行,即使有多个分区级别,这也会为每个父表提供表大小:
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', 'r')
-- 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,
array_agg(relid :: REGCLASS) AS all_partitions,
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
实际上,每个分区只需要一行。用
psu.relname
替换group by中的pi.inhparent
,并将select中的pi.inhparent::regclass替换为win的父表名称。