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

前端 未结 15 2087
无人及你
无人及你 2020-11-22 12:31

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;
         


        
相关标签:
15条回答
  • 2020-11-22 13:10

    I wanted the total from all tables + a list of tables with their counts. A little like a performance chart of where most time was spent

    WITH results AS ( 
      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'
         GROUP BY schemaname, relname, reltuples
    )
    
    SELECT * FROM results
    UNION
    SELECT 'all' AS schemaname, 'all' AS relname, SUM(reltuples) AS "reltuples" FROM results
    
    ORDER BY reltuples DESC
    

    You could of course put a LIMIT clause on the results in this version too so that you get the largest n offenders as well as a total.

    One thing that should be noted about this is that you need to let it sit for a while after bulk imports. I tested this by just adding 5000 rows to a database across several tables using real import data. It showed 1800 records for about a minute (probably a configurable window)

    This is based from https://stackoverflow.com/a/2611745/1548557 work, so thank you and recognition to that for the query to use within the CTE

    0 讨论(0)
  • 2020-11-22 13:12

    I like Daniel Vérité's answer. But when you can't use a CREATE statement you can either use a bash solution or, if you're a windows user, a powershell one:

    # You don't need this if you have pgpass.conf
    $env:PGPASSWORD = "userpass"
    
    # Get table list
    $tables = & 'C:\Program Files\PostgreSQL\9.4\bin\psql.exe' -U user -w -d dbname -At -c "select table_name from information_schema.tables where table_type='BASE TABLE' AND table_schema='schema1'"
    
    foreach ($table in $tables) {
        & 'C:\path_to_postresql\bin\psql.exe' -U root -w -d dbname -At -c "select '$table', count(*) from $table"
    }
    
    0 讨论(0)
  • 2020-11-22 13:14

    I made a small variation to include all tables, also for non-public tables.

    CREATE TYPE table_count AS (table_schema TEXT,table_name TEXT, num_rows INTEGER); 
    
    CREATE OR REPLACE FUNCTION count_em_all () RETURNS SETOF table_count  AS '
    DECLARE 
        the_count RECORD; 
        t_name RECORD; 
        r table_count%ROWTYPE; 
    
    BEGIN
        FOR t_name IN 
            SELECT table_schema,table_name
            FROM information_schema.tables
            where table_schema !=''pg_catalog''
              and table_schema !=''information_schema''
            ORDER BY 1,2
            LOOP
                FOR the_count IN EXECUTE ''SELECT COUNT(*) AS "count" FROM '' || t_name.table_schema||''.''||t_name.table_name
                LOOP 
                END LOOP; 
    
                r.table_schema := t_name.table_schema;
                r.table_name := t_name.table_name; 
                r.num_rows := the_count.count; 
                RETURN NEXT r; 
            END LOOP; 
            RETURN; 
    END;
    ' LANGUAGE plpgsql; 
    

    use select count_em_all(); to call it.

    Hope you find this usefull. Paul

    0 讨论(0)
  • 2020-11-22 13:16

    Not sure if an answer in bash is acceptable to you, but FWIW...

    PGCOMMAND=" psql -h localhost -U fred -d mydb -At -c \"
                SELECT   table_name
                FROM     information_schema.tables
                WHERE    table_type='BASE TABLE'
                AND      table_schema='public'
                \""
    TABLENAMES=$(export PGPASSWORD=test; eval "$PGCOMMAND")
    
    for TABLENAME in $TABLENAMES; do
        PGCOMMAND=" psql -h localhost -U fred -d mydb -At -c \"
                    SELECT   '$TABLENAME',
                             count(*) 
                    FROM     $TABLENAME
                    \""
        eval "$PGCOMMAND"
    done
    
    0 讨论(0)
  • 2020-11-22 13:21

    The hacky, practical answer for people trying to evaluate which Heroku plan they need and can't wait for heroku's slow row counter to refresh:

    Basically you want to run \dt in psql, copy the results to your favorite text editor (it will look like this:

     public | auth_group                     | table | axrsosvelhutvw
     public | auth_group_permissions         | table | axrsosvelhutvw
     public | auth_permission                | table | axrsosvelhutvw
     public | auth_user                      | table | axrsosvelhutvw
     public | auth_user_groups               | table | axrsosvelhutvw
     public | auth_user_user_permissions     | table | axrsosvelhutvw
     public | background_task                | table | axrsosvelhutvw
     public | django_admin_log               | table | axrsosvelhutvw
     public | django_content_type            | table | axrsosvelhutvw
     public | django_migrations              | table | axrsosvelhutvw
     public | django_session                 | table | axrsosvelhutvw
     public | exercises_assignment           | table | axrsosvelhutvw
    

    ), then run a regex search and replace like this:

    ^[^|]*\|\s+([^|]*?)\s+\| table \|.*$
    

    to:

    select '\1', count(*) from \1 union/g
    

    which will yield you something very similar to this:

    select 'auth_group', count(*) from auth_group union
    select 'auth_group_permissions', count(*) from auth_group_permissions union
    select 'auth_permission', count(*) from auth_permission union
    select 'auth_user', count(*) from auth_user union
    select 'auth_user_groups', count(*) from auth_user_groups union
    select 'auth_user_user_permissions', count(*) from auth_user_user_permissions union
    select 'background_task', count(*) from background_task union
    select 'django_admin_log', count(*) from django_admin_log union
    select 'django_content_type', count(*) from django_content_type union
    select 'django_migrations', count(*) from django_migrations union
    select 'django_session', count(*) from django_session
    ;
    

    (You'll need to remove the last union and add the semicolon at the end manually)

    Run it in psql and you're done.

                ?column?            | count
    --------------------------------+-------
     auth_group_permissions         |     0
     auth_user_user_permissions     |     0
     django_session                 |  1306
     django_content_type            |    17
     auth_user_groups               |   162
     django_admin_log               |  9106
     django_migrations              |    19
    [..]
    
    0 讨论(0)
  • 2020-11-22 13:22

    This worked for me

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

    0 讨论(0)
提交回复
热议问题