我有一个更新记录值的过程,我想针对表中的所有记录(超过30k记录)启动它,过程执行时间从2到10秒,因为它取决于网络负载。
现在我在做UPDATE表SET field = procedure_name(paramns);但是有了这么多的记录,处理所有表格需要40分钟。
现在我使用4个不同的连接,使用分叉到背景并触发查询,并将WHERE子句设置为遍历行ID的模数以加快速度,(WHERE id_field%4 =)这样做效果很好并且减少表填充到〜 10分钟。
但我想避免使用cron,shell作业和多个连接,我知道它可以用libpq完成,但有没有办法启动查询(4种不同的非阻塞查询)而不是在单一连接中等到它结束执行?
或者,如果有人可以指出我有关如何编写该函数的一些线索,使用postgres内部,或者只是在C中并将其绑定为存储过程?
干杯大流士
答案 0 :(得分:1)
我对这个问题有一个肯定的答案 - 如果你愿意与我们分享你的ab锻炼!我一分钟都胖了,我自己也需要答案......
好的,无论如何我都会回答。
如果要在一个数据库服务器上更新一个表,在40分钟内单线程更新,在10分钟内更新4个线程,则瓶颈不是数据库服务器;否则,它会陷入I / O陷入困境。如果你正在执行一堆UPDATES,每条记录一次呼叫,网络往返时间就会让你失望。
我很确定是这种情况,而不是它是数据库的I / O瓶颈或者可能是procedure_name(paramns);需要很长时间。 (如果那是2-10秒的过程,则需要2500分钟才能完成30K记录)。我确信的原因是开始4个并发处理的时间减少了1/4。所以特别是它不是数据库服务器上的i / o问题。
这可能是将业务逻辑放在服务器上的SP中的借口。不幸的是,优化意味着违反规则。结果是难以维护。但是,呃!!
然而,最佳解决方案将设置为使用“批量更新”查询。这可能意味着您必须采取以下几个奇怪且不直观的步骤:
我没有做任何保证,特别是当我低头看着我肥胖的肚子时,但是,这有可能将你的更新工作融化到不到一分钟。
答案 1 :(得分:1)
可以一次更新多行。下面是postgres中的一个例子:
UPDATE
table_name
SET
column_name = temp.column_name
FROM
(VALUES
(<id1>, <value1>),
(<id2>, <value2>),
(<id3>, <value3>)
) AS temp("id", "column_name")
WHERE
table_name.id = temp.id
答案 2 :(得分:0)
PHP具有asynchrone个查询的一些功能:
不了解其他编程语言,你必须深入研究手册。
答案 3 :(得分:0)
我想你不能。单个连接可以立即处理单个查询。它在libpq文档章节“异步命令处理”中有描述:
“成功调用PQsendQuery之后,调用PQgetResult一次或多次以获取结果。在PQgetResult返回空指针之前,不能再次调用PQsendQuery(在同一连接上),表明命令已完成。”