PostgreSQL的。可以并行运行更新查询吗?

时间:2012-10-17 09:16:19

标签: postgresql parallel-processing sql-update

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

UPDATE MyTable SET Statistic = GetStatistic(ID);

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

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

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

1 个答案:

答案 0 :(得分:10)

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

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

您可以做的是将工作分成块并将其交给工人。你曾经提到过:

  

我可以修改查询以获取postgre来计算paralel中的GetStatistic   对于不同的行,同时使用所有可用的CPU?

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

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

通过将GetStatistic函数转换为可内联的SQL函数或视图,而不是大概是一个循环繁重的程序PL / pgSQL函数,很可能会使你的{{1}}函数更快。如果你展示了这个功能,它可能会有所帮助。