代码之家  ›  专栏  ›  技术社区  ›  canni

Postgres:如何在同一时间触发多个查询?

  •  2
  • canni  · 技术社区  · 14 年前

    我有一个更新记录值的过程,我想对表中的所有记录(超过30k条记录)启动它,过程执行时间从2秒到10秒,因为它取决于网络负载。

    现在,我正在执行updatetablesetfield=procedure\u name(paramns);但是对于这么多的记录,处理所有表需要40分钟。

    但是我想避免使用cron、shell作业和多个连接,我知道可以使用libpq来完成,但是有没有一种方法可以启动一个查询(4个不同的非阻塞查询)并且不要等到它在单个连接中结束执行?

    或者,如果有人能给我指出一些关于如何编写该函数的线索,使用postgres内部构件,或者简单地用C语言将其绑定为存储过程?

    干杯,大流士

    4 回复  |  直到 14 年前
        1
  •  1
  •   FastAl    14 年前

    我对这个问题有一个确定的答案-如果你愿意和我们分享你的ab训练是什么!!!我越来越胖了,我自己也需要答案。。。

    好吧,我还是会回答的。

    如果在一个数据库服务器上更新一个表,在40分钟内“单线程”更新,在10分钟内用4个线程更新,那么瓶颈不是数据库服务器;否则,它将陷入I/O中。如果你正在执行一堆更新,每个记录一个调用,那么网络往返时间就要把你累死了。

    这可能是将业务逻辑放在服务器上的SP中的一个借口。不幸的是,优化意味着打破规则。其后果是维护困难。但是,嗯!!

    然而, 最佳解决方案 将此设置为使用“批量更新”查询。这可能意味着您必须采取一些奇怪且不直观的步骤,例如:

    • 如果多个用户可以同时运行它,这将需要大量的修改。
    • 重构系统,使过程名称(paramns)可以获得它需要处理的所有数据 通过select语句记录。可能需要使用创造性连接。如果它是一个SP,那么现在您当然要将逻辑移到客户端。
    • 使用,使程序创建一个XML或其他可导入的平面文件格式,其中包含要更新的记录的主键和一个或多个新字段值。将所有更新写入此文件,而不是在数据库上执行它们。
    • 在数据库中有一个与此平面文件的布局匹配的临时表
    • 在数据库上运行导入-清除临时表并导入文件
    • 更新temp表和要更新的表的连接,例如updatemytbl,mytemp WHERE myPK=mytempk SET myval=mytempnewval(当然要使用正确的连接语法)。
    • 如果可能的话,你仍然可以把这些都放在一个SP里!

    我没有做任何保证,尤其是当我低头看着我不断发胖的肚子,但是,这有可能融化你的更新工作到一分钟以下。

        2
  •  1
  •   Pieter    11 年前

    可以一次更新多行。以下是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
    
        3
  •  0
  •   Frank Heikens    14 年前

    PHP有一些函数 asynchrone

    • pg_uu2;send_uu2;execute()
    • pg\发送\查询\参数()

    对其他编程语言一无所知,你必须深入阅读手册。

        4
  •  0
  •   Tomasz Myrta    11 年前