我有一个商店程序
DO_STUFF(obj rowFromMyTable)
这需要obj并处理一些数据并将结果保存在一个独立的表中。 因此,处理对象的顺序并不重要。
DO_STUFF(objA); DO_STUFF(objB); < == > DO_STUFF(objB); DO_STUFF(objA);
事情是要创建一个存储过程来处理所有对象,但这只使用一个CPU。
for each obj in (SELECT obj from tblSOURCE)
loop
DO_STUFF(obj);
end loop;
我想在多个CPU中分割进程,以便更快地完成任务
我唯一想到的是使用2个pgAdmin窗口并在每个窗口中运行两个不同的存储过程。
--one window run using the filter
(SELECT obj from tblSOURCE where id between 1 and 100000)
--and the other use
(SELECT obj from tblSOURCE where id between 100001 and 200000)
我应该如何在单一商店程序中执行此操作?
答案 0 :(得分:2)
我喜欢使用一种快速多线程查询的技术是使用 psql 和 GNU Parallel (http://www.gnu.org/software/parallel/parallel_tutorial.html)的组合来允许用于一次运行多个psql命令。
如果创建一个包含循环的包装器存储过程并为其添加参数以获取偏移量和限制,则可以创建快速bash脚本(或Python,Perl等)来生成一系列psql命令这是必要的。
包含命令的文件可以通过管道并行传输,或者将所有可用的CPU或您确定的数字(我经常喜欢使用4个CPU,以便在盒子上保留I / O,但这取决于你的硬件。
假设包装器名为 do_stuff_wrapper(_offset,_limit)。偏移量和限制将适用于选择:
select obj from tblSOURCE offset _offset limit _limit
您生成的psql命令文件(我们称之为parallel.dat)可能如下所示:
psql -X -h HOST -U user database -c "select do_stuff_wrapper(0, 5000);" psql -X -h HOST -U user database -c "select do_stuff_wrapper(5001, 5000);" psql -X -h HOST -U user database -c "select do_stuff_wrapper(10001, 5000);"
等等。
然后你可以运行这样的命令:
cat parallel.dat | parallel -j 4 {}
获取多个以协同方式运行的psql命令。 Parallel也会为您管道IO(如果有的话,例如NOTICE等),以便它按命令顺序结束。
编辑:如果你在Windows上运行,你可以安装Cygwin,然后从那里使用parallel。另一个纯Windows选项是调查Powershell以实现类似于并行的东西(参见Can Powershell Run Commands in Parallel?)。
答案 1 :(得分:1)
两种方法(适用于任何Windows / Linux / Mac):
PostgreSQL 9.6+现在应该能够(自动)在某种程度上并行化您的查询,然后您可能想要了解是否需要自己分解查询。
使用dblink并通过多个回调连接到数据库。关于DBLink的最好的部分是这些可以是即发即忘(即异步)调用,因此可以快速连续调用,然后最终等到它们全部完成(尽管你需要编织等待结果)逻辑自己)。但是,缺点(与同步调用一样)是除非你跟踪过程失败/超时等事情,否则你可能错误地认为,因为调用已成功通过(成功)所有数据都被处理,实际上它可能是调用失败(异步)。
SELECT * FROM dblink_send_query('testconn', 'SELECT do_stuff_wrapper(0, 5000)') AS t1;
SELECT dblink_is_busy('testconn');
SELECT * FROM dblink_get_result('testconn') AS t1(c1 TEXT, c2 TEXT, ....);
更新:使用dblink的异步函数进行说明。