我通常不依赖统计信息,尤其是在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();
称呼它。
希望对您有用。 保罗