我正在使用一个计划脚本,它将 PostgreSQL 数据库的(新)行导出到一个文本文件中。此脚本的多个实例也为多个 DB 运行:
COPY (SELECT ... FROM ... GROUP BY zzz) TO STDOUT >file.csv
Run Code Online (Sandbox Code Playgroud)
为了对 file.csv 进行一致性检查,我然后运行查询以获取查询的行数COPY
:
SELECT count(0) FROM ... GROUP BY zzz >linecount
Run Code Online (Sandbox Code Playgroud)
在 bash 脚本中,检查两者是否相等,如果是这种情况,脚本继续运行,否则它会停止并报告错误(这种情况很少发生,但确实发生了 - 我还没有弄清楚原因)
问题,查询结果比较大(大概count(0)
5-10分钟),基本上跑了两次(虽然花的时间更短,但还是3-7分钟)
是否有 PostgreSQL 函数来获取最后一个查询的行数?如果是这种情况,我可以大大减少数据库负载并缩短导出时间。
我已经研究过ROW_COUNT
,但它似乎只对UPDATE/INSERT
而非有效,SELECT
出于简单的原因,我还想避免使用函数。
我愿意接受其他建议,例如首先查询临时表,然后从那里导出(也许count(0)
会更快)?
Debian 7 Wheezy、SSD、32GB 内存、PostgreSQL 9.1
更新@克雷格林格
我同意一致性检查在设计上有些“缺陷”。我曾经注意到导入检查有一个我无法解释的问题,然后我再次运行导出,并且文件的行与之前的行不同:
Rowcount DB/LinecountF:532395/532014
rowcount: SELECT count(0)... as described originally
linecount = wc -l
Run Code Online (Sandbox Code Playgroud)
他们作为 cronjobs 运行,我还没有弄清楚为什么这些行丢失了。第二次运行相同的脚本,一切都很好。它很少发生,但日志文件没有说明任何内容(或来自 cron 的邮件结果)。
我没有检查 PSQL 强硬的退出状态(因为我在自己的检查中建立了)。我去做。
如果您愿意放弃写入 STDOUT,您可以使用 PL/pgSQL 函数获得 COPY 导出的行数,如下所示:
CREATE OR REPLACE FUNCTION copyout(query text, output_path text) RETURNS integer AS $fn$
DECLARE
result integer;
BEGIN
EXECUTE 'COPY (' || query || $$) TO '$$ || output_path || $$'$$;
GET DIAGNOSTICS result = ROW_COUNT;
RETURN result;
END
$fn$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
执行如下(注意路径在服务器上而不是客户端上):
> SELECT copyout('SELECT * FROM mytable', '/tmp/myfile.csv');
copyout
---------
981
(1 row)
Run Code Online (Sandbox Code Playgroud)
但是 - 刚刚发现这是在 9.3 中添加的(请参阅9.3 发行说明)。对不起。