Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you find the row count for all your tables in Postgres

I'm looking for a way to find the row count for all my tables in Postgres. I know I can do this one table at a time with:

SELECT count(*) FROM table_name; 

but I'd like to see the row count for all the tables and then order by that to get an idea of how big all my tables are.

like image 940
mmrobins Avatar asked Apr 07 '10 23:04

mmrobins


People also ask

How do you find the number of rows in a table in Postgres?

The basic SQL standard query to count the rows in a table is: SELECT count(*) FROM table_name; This can be rather slow because PostgreSQL has to check visibility for all rows, due to the MVCC model.

How do you get Rowcount?

Getting MySQL row count of all tables in a specific database First, get all table names in the database. Second, construct an SQL statement that includes all SELECT COUNT(*) FROM table_name statements for all tables separated by UNION . Third, execute the SQL statement using a prepared statement.

How do I count in PostgreSQL?

PostgreSQL COUNT SELECTSELECT COUNT ( [*], [DISTINCT] [column_name] ) FROM TABLE_NAME; Let's dig a little deeper into the syntax shown above: SELECT – This is used to select certain columns from the database. COUNT – This is used to count the number of records in this table.


1 Answers

There's three ways to get this sort of count, each with their own tradeoffs.

If you want a true count, you have to execute the SELECT statement like the one you used against each table. This is because PostgreSQL keeps row visibility information in the row itself, not anywhere else, so any accurate count can only be relative to some transaction. You're getting a count of what that transaction sees at the point in time when it executes. You could automate this to run against every table in the database, but you probably don't need that level of accuracy or want to wait that long.

WITH tbl AS   (SELECT table_schema,           TABLE_NAME    FROM information_schema.tables    WHERE TABLE_NAME not like 'pg_%'      AND table_schema in ('public')) SELECT table_schema,        TABLE_NAME,        (xpath('/row/c/text()', query_to_xml(format('select count(*) as c from %I.%I', table_schema, TABLE_NAME), FALSE, TRUE, '')))[1]::text::int AS rows_n FROM tbl ORDER BY rows_n DESC; 

The second approach notes that the statistics collector tracks roughly how many rows are "live" (not deleted or obsoleted by later updates) at any time. This value can be off by a bit under heavy activity, but is generally a good estimate:

SELECT schemaname,relname,n_live_tup    FROM pg_stat_user_tables  ORDER BY n_live_tup DESC; 

That can also show you how many rows are dead, which is itself an interesting number to monitor.

The third way is to note that the system ANALYZE command, which is executed by the autovacuum process regularly as of PostgreSQL 8.3 to update table statistics, also computes a row estimate. You can grab that one like this:

SELECT    nspname AS schemaname,relname,reltuples FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace) WHERE    nspname NOT IN ('pg_catalog', 'information_schema') AND   relkind='r'  ORDER BY reltuples DESC; 

Which of these queries is better to use is hard to say. Normally I make that decision based on whether there's more useful information I also want to use inside of pg_class or inside of pg_stat_user_tables. For basic counting purposes just to see how big things are in general, either should be accurate enough.

like image 73
Greg Smith Avatar answered Sep 21 '22 08:09

Greg Smith