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

前端 未结 15 2066
无人及你
无人及你 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 12:59

    Here is a solution that does not require functions to get an accurate count for each table:

    select table_schema, 
           table_name, 
           (xpath('/row/cnt/text()', xml_count))[1]::text::int as row_count
    from (
      select table_name, table_schema, 
             query_to_xml(format('select count(*) as cnt from %I.%I', table_schema, table_name), false, true, '') as xml_count
      from information_schema.tables
      where table_schema = 'public' --<< change here for the schema you want
    ) t
    

    query_to_xml will run the passed SQL query and return an XML with the result (the row count for that table). The outer xpath() will then extract the count information from that xml and convert it to a number

    The derived table is not really necessary, but makes the xpath() a bit easier to understand - otherwise the whole query_to_xml() would need to be passed to the xpath() function.

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

    Simple Two Steps:
    (Note : No need to change anything - just copy paste)
    1. create function

    create function 
    cnt_rows(schema text, tablename text) returns integer
    as
    $body$
    declare
      result integer;
      query varchar;
    begin
      query := 'SELECT count(1) FROM ' || schema || '.' || tablename;
      execute query into result;
      return result;
    end;
    $body$
    language plpgsql;
    

    2. Run this query to get rows count for all the tables

    select sum(cnt_rows) as total_no_of_rows from (select 
      cnt_rows(table_schema, table_name)
    from information_schema.tables
    where 
      table_schema not in ('pg_catalog', 'information_schema') 
      and table_type='BASE TABLE') as subq;
    

    or

    To get rows counts tablewise

    select
      table_schema,
      table_name, 
      cnt_rows(table_schema, table_name)
    from information_schema.tables
    where 
      table_schema not in ('pg_catalog', 'information_schema') 
      and table_type='BASE TABLE'
    order by 3 desc;
    
    0 讨论(0)
  • 2020-11-22 13:01

    If you don't mind potentially stale data, you can access the same statistics used by the query optimizer.

    Something like:

    SELECT relname, n_tup_ins - n_tup_del as rowcount FROM pg_stat_all_tables;
    
    0 讨论(0)
  • 2020-11-22 13:01

    I usually don't rely on statistics, especially in PostgreSQL.

    SELECT table_name, dsql2('select count(*) from '||table_name) as rownum
    FROM information_schema.tables
    WHERE table_type='BASE TABLE'
        AND table_schema='livescreen'
    ORDER BY 2 DESC;
    
    CREATE OR REPLACE FUNCTION dsql2(i_text text)
      RETURNS int AS
    $BODY$
    Declare
      v_val int;
    BEGIN
      execute i_text into v_val;
      return v_val;
    END; 
    $BODY$
      LANGUAGE plpgsql VOLATILE
      COST 100;
    
    0 讨论(0)
  • 2020-11-22 13:04

    I don't remember the URL from where I collected this. But hope this should help you:

    CREATE TYPE table_count AS (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 
                c.relname
            FROM
                pg_catalog.pg_class c LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
            WHERE 
                c.relkind = ''r''
                AND n.nspname = ''public'' 
            ORDER BY 1 
            LOOP
                FOR the_count IN EXECUTE ''SELECT COUNT(*) AS "count" FROM '' || t_name.relname 
                LOOP 
                END LOOP; 
    
                r.table_name := t_name.relname; 
                r.num_rows := the_count.count; 
                RETURN NEXT r; 
            END LOOP; 
            RETURN; 
    END;
    ' LANGUAGE plpgsql; 
    

    Executing select count_em_all(); should get you row count of all your tables.

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

    Here is a much simpler way.

    tables="$(echo '\dt' | psql -U "${PGUSER}" | tail -n +4 | head -n-2 | tr -d ' ' | cut -d '|' -f2)"
    for table in $tables; do
    printf "%s: %s\n" "$table" "$(echo "SELECT COUNT(*) FROM $table;" | psql -U "${PGUSER}" | tail -n +3 | head -n-2 | tr -d ' ')"
    done
    

    output should look like this

    auth_group: 0
    auth_group_permissions: 0
    auth_permission: 36
    auth_user: 2
    auth_user_groups: 0
    auth_user_user_permissions: 0
    authtoken_token: 2
    django_admin_log: 0
    django_content_type: 9
    django_migrations: 22
    django_session: 0
    mydata_table1: 9011
    mydata_table2: 3499
    

    you can update the psql -U "${PGUSER}" portion as needed to access your database

    note that the head -n-2 syntax may not work in macOS, you could probably just use a different implementation there

    Tested on psql (PostgreSQL) 11.2 under CentOS 7


    if you want it sorted by table, then just wrap it with sort

    for table in $tables; do
    printf "%s: %s\n" "$table" "$(echo "SELECT COUNT(*) FROM $table;" | psql -U "${PGUSER}" | tail -n +3 | head -n-2 | tr -d ' ')"
    done | sort -k 2,2nr
    

    output;

    mydata_table1: 9011
    mydata_table2: 3499
    auth_permission: 36
    django_migrations: 22
    django_content_type: 9
    authtoken_token: 2
    auth_user: 2
    auth_group: 0
    auth_group_permissions: 0
    auth_user_groups: 0
    auth_user_user_permissions: 0
    django_admin_log: 0
    django_session: 0
    
    0 讨论(0)
提交回复
热议问题