相关疑难解决方法(0)

如何在PostgreSQL中进行大型非阻塞更新?

我想在PostgreSQL中对表进行大量更新,但我不需要在整个操作中维护事务完整性,因为我知道我正在更改的列不会被写入或读取更新.我想知道psql控制台中是否有一种简单的方法可以更快地完成这些类型的操作.

例如,假设我有一个名为"orders"的表,有3500万行,我想这样做:

UPDATE orders SET status = null;
Run Code Online (Sandbox Code Playgroud)

为避免被转移到offtopic讨论,让我们假设3500万列的所有状态值当前都设置为相同(非空)值,从而使索引无用.

此语句的问题是需要很长时间才能生效(仅因为锁定),并且所有更改的行都将被锁定,直到整个更新完成.此更新可能需要5个小时,而类似

UPDATE orders SET status = null WHERE (order_id > 0 and order_id < 1000000);
Run Code Online (Sandbox Code Playgroud)

可能需要1分钟.超过3500万行,执行上述操作并将其分成35块只需要35分钟,节省了4小时25分钟.

我可以用脚本进一步分解它(在这里使用伪代码):

for (i = 0 to 3500) {
  db_operation ("UPDATE orders SET status = null
                 WHERE (order_id >" + (i*1000)"
             + " AND order_id <" + ((i+1)*1000) " +  ")");
}
Run Code Online (Sandbox Code Playgroud)

此操作可能仅在几分钟内完成,而不是35分钟.

所以这归结为我真正的要求.我不想写一个怪异的脚本来分解操作,每次我想做这样一个大的一次性更新.有没有办法在SQL中完成我想要的东西?

postgresql dblink transactions plpgsql sql-update

61
推荐指数
3
解决办法
3万
查看次数

Postgres是否支持嵌套或自治事务?

我有一种情况,我必须提交一部分代码作为自己的事务.
我创建了一个表subtransaction_tbl:

CREATE TABLE subtransaction_tbl
(
  entryval integer
)
Run Code Online (Sandbox Code Playgroud)

和语言plpython3u中的函数:

CREATE FUNCTION subtransaction_nested_test_t() RETURNS void
AS $$
plpy.execute("INSERT INTO subtransaction_tbl VALUES (1)")
with plpy.subtransaction():
    plpy.execute("INSERT INTO subtransaction_tbl VALUES (2)")
$$ LANGUAGE plpython3u;
Run Code Online (Sandbox Code Playgroud)

第一种情况:

BEGIN TRANSACTION;
INSERT INTO subtransaction_tbl VALUES (4);
select  subtransaction_nested_test_t();
COMMIT TRANSACTION;
Run Code Online (Sandbox Code Playgroud)

表中的条目是正确的:1,2,4

第二种情况:

BEGIN TRANSACTION;
INSERT INTO subtransaction_tbl VALUES (4);
select  subtransaction_nested_test_t();
ROLLBACK TRANSACTION;
Run Code Online (Sandbox Code Playgroud)

表中的值未填充

我预计12应该添加到表中,subtransaction_tbl但令我惊讶的是没有插入任何值.我想象一个新的子事务由函数打开,它不应该依赖于父事务.如果我是对的,请告诉我.

Postgres有自动交易吗?或者我是否必须修改我的plpython3u函数?

sql postgresql transactions python-3.x

17
推荐指数
2
解决办法
2万
查看次数