I\'m looking for a query that returns a result of the form for any database (see example below supposing total space used by the database is 40GB)
schema | si
https://www.depesz.com/2018/02/17/which-schema-is-using-the-most-disk-space/
shows a solution that counts the TOAST tabels as well. Tested on PG12:
WITH recursive all_elements AS (
SELECT 'base/' || l.filename AS path, x.*
FROM
pg_ls_dir('base/') AS l (filename),
LATERAL pg_stat_file( 'base/' || l.filename) AS x
UNION ALL
SELECT 'pg_tblspc/' || l.filename AS path, x.*
FROM
pg_ls_dir('pg_tblspc/') AS l (filename),
LATERAL pg_stat_file( 'pg_tblspc/' || l.filename) AS x
UNION ALL
SELECT
u.path || '/' || l.filename, x.*
FROM
all_elements u,
lateral pg_ls_dir(u.path) AS l(filename),
lateral pg_stat_file( u.path || '/' || l.filename ) AS x
WHERE
u.isdir
), all_files AS (
SELECT path, SIZE FROM all_elements WHERE NOT isdir
), interesting_files AS (
SELECT
regexp_replace(
regexp_replace(f.path, '.*/', ''),
'\.[0-9]*$',
''
) AS filename,
SUM( f.size )
FROM
pg_database d,
all_files f
WHERE
d.datname = current_database() AND
f.path ~ ( '/' || d.oid || E'/[0-9]+(\\.[0-9]+)?$' )
GROUP BY filename
)
SELECT
n.nspname AS schema_name,
SUM( f.sum ) AS total_schema_size
FROM
interesting_files f
JOIN pg_class c ON f.filename::oid = c.relfilenode
LEFT OUTER JOIN pg_class dtc ON dtc.reltoastrelid = c.oid AND c.relkind = 't'
JOIN pg_namespace n ON COALESCE( dtc.relnamespace, c.relnamespace ) = n.oid
GROUP BY
n.nspname
ORDER BY
total_schema_size DESC