我正在寻找一种方法,为我在Postgres中所有的表找到行数。我知道我可以一次做一张表:

SELECT count(*) FROM table_name;

但我想看看所有表的行数,然后按它排序,以了解所有表的大小。


当前回答

如果您不介意可能过时的数据,您可以访问查询优化器使用的相同统计信息。

喜欢的东西:

SELECT relname, n_tup_ins - n_tup_del as rowcount FROM pg_stat_all_tables;

其他回答

我不记得我收集这个的URL了。但希望这能帮助到你:

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; 

执行select count_em_all();应该得到所有表的行数。

有三种方法可以得到这种计数,每种方法都有各自的权衡。

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;

第二种方法指出,统计信息收集器在任何时候大致跟踪有多少行是“活动的”(没有被后来的更新删除或废弃)。这个值在剧烈活动时可能会偏离一点,但通常是一个很好的估计:

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

这还可以显示有多少行已死,这本身就是一个值得监视的有趣数字。

第三种方法是注意到系统ANALYZE命令,从PostgreSQL 8.3开始由autovacuum进程定期执行以更新表统计信息,它也计算行估计。你可以像这样抓取它:

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;

很难说使用这些查询中哪一个更好。通常,我根据是否有更多有用的信息也想在pg_class中使用,还是在pg_stat_user_tables中使用来做出决定。出于基本的计数目的,只是为了了解事物的总体大小,这两种方法都应该足够准确。

我通常不依赖于统计数据,尤其是在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;

您可以使用此查询生成所有表名及其计数

select ' select  '''|| tablename  ||''', count(*) from ' || tablename ||' 
union' from pg_tables where schemaname='public'; 

上述查询的结果将是

select  'dim_date', count(*) from dim_date union 
select  'dim_store', count(*) from dim_store union
select  'dim_product', count(*) from dim_product union
select  'dim_employee', count(*) from dim_employee union

您需要删除最后一个联合符,并在末尾添加分号!!

select  'dim_date', count(*) from dim_date union 
select  'dim_store', count(*) from dim_store union
select  'dim_product', count(*) from dim_product union
select  'dim_employee', count(*) from dim_employee  **;**

跑! !

下面的查询将给出每个表的行数和大小

选择table_schema, table_name, pg_relation_size('“' | | table_schema | |”“。”“| | table_name | |”“”)/ 1024/1024 size_MB, (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 从information_schema.tables order by size_MB