I have tried to select a list of databases and select all tables from each database, ordering the first ten tables by their size – including their indexes- through PL/pgSQL, but I have had a problem to join the query for the database with the query for the tables and their sizes included in the specific database.
I have started like this:
DO $$
DECLARE
database_name pg_database.datname%TYPE;
total_table_size pg_tables.tablename%TYPE;
rec record;
BEGIN
FOR rec IN SELECT datname
FROM pg_database
LOOP
database_name := rec.datname;
raise notice 'Database name: %', database_name;
SELECT tablename,
pg_total_relation_size(table_name) AS total_table_size
FROM pg_tables
INTO table_name, total_table_size
ORDER BY pg_total_relation_size(relid) DESC
LIMIT 10;
END LOOP;
END;
$$;
I do not know how to specify that I want the first ten table names and their sizes ordered from the largest to the smallest of the present selected database. Could anyone help me with it, please?
I thought about joining the queries somehow, but I have not found a column that I could use to make the join.
I have searched similar problems in the community, but I did not find something so specific.
Thanks in advance.
2
Answers
If you are connected to 1 database I am not sure you can get information from another database. Possibly it could be done with a dblink.
Below will give a list of table sizes within the current database
LIMIT 10
. You’re just duplicating the same 10 rows as many times as there are databases in your catalog, but still those are results for the current database you’re connected to.pg_size_pretty()
in your select section to make it readable.pg_tables
it’s underschemaname
, ininformation_schema.tables
it’s undertable_schema
. The recommendation ispg_database
catalog, there’s no cluster-wide catalog for namespaces and tables. You needpostgres_fdw
ordblink
for databases to interact.CREATE VIEW v_pg_total_relation_sizes
on each of your databases (here are examples you can just prepend withcreate view ... as
). To make it present by default in databases created in the future, create one intemplate1
database as well. Make them visible throughpostgres_fdw
, then create a view that’s aunion
of the local one and all the linked ones. Depending on how large your databases are, if this gets slow you might want to consider making it amaterialized view
to cache it.