Find number of rows on each table in a schema in postgres - postgresql

I'm running this in Postgres 9.4 to get the number of rows on each table in a particular schema:
select table_schema, table_name,
(xpath('/row/count/text()', query_to_xml('select count(*) from '||format('%I.%I', table_schema, table_name), true, true, '')))[1]::text::int as row_count
from information_schema.tables
where table_schema = 'pricing'
It works in Postgres 9.4 but in Postgres 8.4 I get an error saying format function doesn't exist, is there a similar function in postgres 8.4?
In postgres 8.4 I get this:
function format(unknown, information_schema.sql_identifier,
information_schema.sql_identifier) does not exist
Thanks!

All the table row counts in all schema
SELECT relname, n_tup_ins - n_tup_del as rowcount FROM pg_stat_all_tables;
All the table row counts in the given schema
SELECT
nspname AS schemaname,relname,reltuples
FROM pg_class C
LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
WHERE
nspname IN ('schema_name') AND
relkind='r'
ORDER BY reltuples DESC;

Related

Select table size and row counts for specific schema

I need to have a query that would give me the information for each table in specific schema. The information would be the size of the table (best in Mb) and also the row counts. I prepared some query as below but not sure if the result is in megabytes. Moreover i do not know how to get the row counts from information_schema.tables. Can somebody help?
This is my current query:
select table_name, pg_relation_size(quote_ident(table_name))
from information_schema.tables
where table_schema = 'myschema'
order by 2;
EDIT:
By this i can get row counts nevertheless do not know how to filter based on specific schema and how to add table size in Mb to it.
select nspname as schema, relname as tablename,
reltuples as rowcounts
from pg_class c JOIN pg_catalog.pg_namespace n
ON n.oid = c.relnamespace where relkind='r'
and relname like 't%'
order by nspname, reltuples desc;
You can get the size of the table in megabytes using the pg_relation_size function. By default the function will return the result in bytes, but you can convert the result to megabytes. Also, to filter by a specific scheme, use the table_schema entry from information_schema.tables.
SELECT
table_name,
(pg_relation_size(quote_ident(table_name)) / 1024 /1024) size,
reltuples as rowcounts FROM information_schema.tables ist
left join pg_class pc on pc.relname = ist.table_name
WHERE table_schema = 'public'
Demo in sql<>daddy.io

How to list MAX(id) of all tables given the db schema name?

I am looking for a pgsql query to pull the last PK for all tables given the db schema.
Need this for my db migration work.
You can do this with a variation of a dynamic row count query:
with pk_list as (
select tbl_ns.nspname as table_schema,
tbl.relname as table_name,
cons.conname as pk_name,
col.attname as pk_column
from pg_class tbl
join pg_constraint cons on tbl.oid = cons.conrelid and cons.contype = 'p'
join pg_namespace tbl_ns on tbl_ns.oid = tbl.relnamespace
join pg_attribute col on col.attrelid = tbl.oid and col.attnum = cons.conkey[1]
join pg_type typ on typ.oid = col.atttypid
where tbl.relkind = 'r'
and cardinality(cons.conkey) = 1 -- only single column primary keys
and tbl_ns.nspname not in ('pg_catalog', 'information_schema')
and typ.typname in ('int2','int4','int8','varchar','numeric','float4','float8','date','timestamp','timestamptz')
and has_table_privilege(format('%I.%I', tbl_ns.nspname, tbl.relname), 'select')
), maxvals as (
select table_schema, table_name, pk_column,
(xpath('/row/max/text()',
query_to_xml(format('select max(%I) from %I.%I', pk_column, table_schema, table_name), true, true, ''))
)[1]::text as max_val
from pk_list
)
select table_schema,
table_name,
pk_column,
max_val
from maxvals;
The first CTE (pk_list ) retrieves the name of the primary key column for each "user" table (that is: tables that are not system tables)
The second CTE (maxvals) then creates a select statement that retrieves the max value for each PK column from the first CTE and runs that query using query_to_xml(). The xpath() function is then used to parse the XML and return the max value as a text value (so it's possible to mix numbers and varchars)
The final select then simply displays the result from that.
The above has the following restrictions:
Only single-column primary keys are considered
It only deals with data types that support using max() on them (e.g. UUID columns are not included)

How to get schema of a table if I have the oid (Postgres 9.5.1)?

I'm trying to figure out how to get the schema of a table if I have the oid in Postgres 9.5.1. I tried using information_schema but can't figure out which table I use to join with the oid.
You need to join pg_namespace to pg_class
select nsp.nspname as schema_name, tbl.relname as table_name
from pg_namespace nsp
join pg_class tbl on nsp.oid = tbl.relnamespace
where tbl.oid = 42;

Record table and schema sizes in PostgreSQL

Is thre a simple way to query for the size of a postgres database?
I am trying to do something like this:
select 'session_metrics',pg_size_pretty(pg_total_relation_size('schema1.session_metrics'))
union
select 'transaction_metrics',pg_size_pretty(pg_total_relation_size('schema1.transaction_metrics'))
union
select 'cookie_user_metrics',pg_size_pretty(pg_total_relation_size('schema1.cookie_user_metrics'))
union
select 'cookie_transaction_metrics',pg_size_pretty(pg_total_relation_size('schema1.cookie_transaction_metrics'));
And store those values in a table so that I can later easily track the growth rates of my tables.
The problem is I now have over 50 different tables and I don't want to add a line of query every time I create a new table.
I would appreciate if someone could orient me to something like:
select table_name, schema_name, size;
The 'table names' table you're looking for is pg_catalog.pg_namespace.
The following query is adapted from the psql \d command:
SELECT n.nspname as "Schema",
c.relname as "Name",
pg_catalog.pg_size_pretty(pg_catalog.pg_table_size(c.oid)) as "Size",
now() as "Timestamp"
FROM pg_catalog.pg_class c
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname <> 'pg_catalog'
AND n.nspname <> 'information_schema'
AND n.nspname !~ '^pg_toast'
I have taken the liberty of adding a timestamp since you are planning to compare sizes over time.

Wrong row count using Catalog Queries

I got this query on the following page:
http://docs.aws.amazon.com/redshift/latest/dg/c_join_PG_examples.html
It lists the table names along with row count. But the row count seems to be wrong (10 times than actual)
select datname, nspname, relname, sum(rows) as rows
from pg_class, pg_namespace, pg_database, stv_tbl_perm
where pg_namespace.oid = relnamespace
and pg_class.oid = stv_tbl_perm.id
and pg_database.oid = stv_tbl_perm.db_id
and datname ='tickit'
group by datname, nspname, relname
order by datname, nspname, relname;
Is the sum(rows) correct?
Here, try mine. It includes the data size as well. :-D
/*
Ordered view of table sizes.
*/
CREATE VIEW my_schema.vw_table_summary
AS
SELECT db_name
,schema_name
,table_name
,TO_CHAR(rows_total,'999,999,999,999') rows_total
,TO_CHAR(rows_sorted,'999,999,999,999') rows_sorted
,CASE WHEN rows_total > 0
THEN ROUND((CONVERT(NUMERIC,rows_sorted)/CONVERT(NUMERIC,rows_total))*100,2)
ELSE 0.00 END percent_sorted
,COALESCE(size_in_gb,0) size_in_gb
FROM (SELECT id table_id
,datname db_name
,nspname schema_name
,relname table_name
,SUM(rows) rows_total
,SUM(sorted_rows) rows_sorted
FROM stv_tbl_perm
JOIN pg_class
ON pg_class.oid = stv_tbl_perm.id
JOIN pg_namespace
ON pg_namespace.oid = relnamespace
JOIN pg_database
ON pg_database.oid = stv_tbl_perm.db_id
WHERE name NOT LIKE 'pg_%'
AND name NOT LIKE 'stl_%'
AND name NOT LIKE 'stp_%'
AND name NOT LIKE 'padb_%'
AND nspname <> 'pg_catalog'
GROUP BY id, datname, nspname, relname
ORDER BY id, datname, nspname, relname) tbl_det
LEFT
JOIN (SELECT tbl table_id
,ROUND(CONVERT(REAL,COUNT(*))/1024,2) size_in_gb
FROM stv_blocklist bloc
GROUP BY tbl) tbl_size
ON tbl_size.table_id = tbl_det.table_id
ORDER BY db_name
,schema_name
,table_name
;