下面是检查PostgreSQL数据库中所有表的实际计数的一个很好的函数。我找到了here。
从我的本地测试来看,似乎该函数仅在完成所有100个表的计数后才返回所有结果。
我想让它更实用。如果我们可以在完成表格后立即保存每个表的结果,那么我们可以检查所有计数作业的进度,而不是等待结束。
我想如果我能在完成第一张表后立即更新此功能的结果,那么这对我的要求是很好的。
在此函数完成第一个表的计数后,您能告诉我如何将结果更新到表中吗?
{{1}}
我决定使用shell脚本来运行下面的函数作为后台进程。该函数将生成一个处理日志文件,以便我可以检查当前进程。
答案 0 :(得分:1)
我认为你的想法很好,但我也认为它不会在PostgreSQL上“开箱即用”。我不是这方面的专家,但是MVCC在PostgreSQL上的工作方式,它基本上可以做所有DML,最好被理解为临时空间,然后当一切按预期工作时,它会全部移动最后。
这有很多优点,最值得注意的是,当有人更新表时,它不会阻止其他人查询那些相同的表。
如果这是Oracle,我认为您可以使用commit,
在存储过程中完成此操作,但这不是Oracle。而且公平地说,Oracle不允许截断在PostgreSQL的方式中在存储过程中回滚,因此有给予和接受。
同样,我不是专家,所以如果我搞砸了一两个细节,请随时纠正我。
所以,回到解决方案。 COULD 实现此目的的一种方法是将服务器设置为远程服务器。像这样的东西会起作用:
CREATE SERVER pgprod
FOREIGN DATA WRAPPER dblink_fdw
OPTIONS (dbname 'postgres', host 'localhost', port '5432');
假设您有一个存储表和计数的表:
create table table_counts (
table_name text not null,
record_count bigint,
constraint table_counts_pk primary key (table_name)
);
如果您不希望看到这些结果发生,那么这样的结果就可以用于单个模式。制作所有模式很容易,所以这只是为了说明:
CREATE or replace FUNCTION rowcount_all(schema_name text)
returns void as
$$
declare
rowcount integer;
tablename text;
begin
for tablename in SELECT c.relname FROM pg_class c
JOIN pg_namespace s ON (c.relnamespace=s.oid)
WHERE c.relkind = 'r' AND s.nspname=schema_name
ORDER BY c.relname
LOOP
EXECUTE 'select count(*) from ' || schema_name || '.' || tablename into rowcount;
insert into table_counts values (schema_name || '.' || tablename, rowcount)
on conflict (table_name) do
update set record_count = rowcount;
END LOOP;
end
$$ language plpgsql;
(这个预设为9.5或更高 - 如果没有,请自己手动卷起)。
但是,由于您希望对表进行实时更新,因此可以将相同的upsert放入dblink表达式中:
perform dblink_exec('pgprod', '
<< your upsert statement here >>
');
当然,DBlink中SQL的格式化现在有点棘手,但是一旦你掌握了它,你可以在后台运行该函数并在运行时查询表以查看动态结果。
我认为这与实时获取信息的必要性有关。