PostgreSQL的.可以在paralell中运行更新查询吗?

Yav*_*sta 10 postgresql parallel-processing sql-update

我有一个10米行的大桌子.我需要为每一行获得一些统计值.例如,我有生成此值的函数GetStatistic(uuid).这个函数运行速度很慢,结果值不经常更改,所以我Statistic在表中创建了列,每天执行一次这样的查询:

UPDATE MyTable SET Statistic = GetStatistic(ID);
Run Code Online (Sandbox Code Playgroud)

在选择查询中,我使用列Statistic而不调用GetStatistic函数.

问题是,我的生产服务器有64个CPU和大量内存,因此几乎所有数据库都可以缓存到RAM,但是这个查询只使用一个CPU,需要2或3个小时才能执行.

GetStatistic函数使用表,在所有UPDATE查询执行期间都是常量.我可以修改查询以获得postgre,使用所有可用的CPU同时计算不同行的并行中的GetStatistic吗?

Cra*_*ger 12

PostgreSQL在单个后端执行每个查询,这是一个具有单个线程的进程.它不能使用多个CPU进行查询.它在单个查询中可以实现的I/O并发性也有些限制,实际上只对位图索引扫描执行并发I/O,否则依赖于操作系统和磁盘系统进行并发I/O.

Pg擅长于许多较小查询的并发加载,并且很容易以这种方式使系统饱和,它只是在为一两个非常大的查询充分利用系统资源.

你能做的就是将工作分成几块,然后交给工人.你曾提到过:

我可以修改查询以获得postgre,使用所有可用的CPU同时计算不同行的并行中的GetStatistic吗?

有许多工具,如DBlink,PL/Proxy,pgbouncerPgPool-II,旨在帮助完成这类工作.或者,您可以自己动手,开始(比方说)8个工作人员,每个工作人员连接到数据库并执行UPDATE ... WHERE id BETWEEN ? AND ?具有非重叠ID范围的语句.更复杂的选择是让队列控制器向工作人员分发大约1000个ID的UPDATE范围,然后该范围要求新的ID .

请注意,64个CPU并不意味着64个并发工作者是理想的.在写入时,您的磁盘I/O也是一个因素.如果将UPDATE事务设置为使用a commit_delay(如果对此数据的业务要求是安全的),synchronous_commit = 'off'则可以帮助您降低I/O成本,然后应显着降低同步的负载.尽管如此,最好的吞吐量可能会远低于64个并发工人.

GetStatistic通过将函数转换为可内联的SQL函数或视图,很可能会使您的函数更快,而不是可能是目前循环繁重的程序PL/pgSQL函数.如果您显示此功能可能会有所帮助.