我通常不依赖统计信息,尤其是在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;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;

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

SELECT relname, n_tup_ins - n_tup_del as rowcount FROM pg_stat_all_tables;

可以通过三种方法进行这种计数,每种方法都有自己的权衡。

如果要计数,则必须执行SELECT语句,就像对每个表使用的语句一样。 这是因为PostgreSQL将行可见性信息保留在行本身中,而不是在其他任何地方,因此任何准确的计数都只能与某些事务有关。 您将获得该交易在执行时看到的内容的计数。 您可以自动执行此操作以对数据库中的每个表运行,但是您可能不需要那种准确性或想要等待那么长时间。

第二种方法指出,统计信息收集器随时会大致跟踪“活动”(未被删除或以后的更新不会删除)多少行。 在繁忙的活动中,此值可能会略有下降,但通常是一个不错的估计:

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

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

第三种方式是要注意,系统ANALYZE命令(它在PostgreSQL 8.3及更高版本中由vacuumum进程定期执行,以更新表统计信息)也计算行估计。 您可以像这样抓住那个:

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内部使用更多有用的信息来做出决定的。 出于基本计数的目的,只是为了查看总体上有多大,这两个都应该足够准确。

我不记得我收集的网址。 但是希望这对您有帮助:

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
            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 
            FOR the_count IN EXECUTE ''SELECT COUNT(*) AS "count" FROM '' || t_name.relname 
            END LOOP; 
            r.table_name := t_name.relname; 
            r.num_rows := the_count.count; 
            RETURN NEXT r; 
        END LOOP; 
        RETURN; 
' LANGUAGE plpgsql; 

执行select count_em_all(); 应该可以让您获得所有表格的行数。

我做了一个小改动,包括所有表,也包括非公开表。

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
            FOR the_count IN EXECUTE ''SELECT COUNT(*) AS "count" FROM '' || t_name.table_schema||''.''||t_name.table_name
            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; 
' LANGUAGE plpgsql; 

使用select count_em_all(); 称呼它。

希望对您有用。 保罗