我有一个存储过程
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)
我应该如何在单个存储过程中执行此操作有什么想法吗?
最佳答案
我喜欢用来获得快速多线程查询的技术是使用 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,然后从那里使用并行。另一个纯 Windows 选项是研究 Powershell 来完成类似于并行的任务(请参阅 Can Powershell Run Commands in Parallel? )。
关于PostgreSQL如何在多个CPU之间拆分查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23376210/