我想在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中完成我想要的东西?
我有一种情况,我必须提交一部分代码作为自己的事务.
我创建了一个表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)
表中的值未填充
我预计1或2应该添加到表中,subtransaction_tbl但令我惊讶的是没有插入任何值.我想象一个新的子事务由函数打开,它不应该依赖于父事务.如果我是对的,请告诉我.
Postgres有自动交易吗?或者我是否必须修改我的plpython3u函数?