当前位置: 首页 > 知识库问答 >
问题:

如何对有序的sql列进行批量更新?

平俊茂
2023-03-14

我正在使用PostgreSQL,并有一个名为table_all的表,其中包含500万行和以下结构:

id|source_id|destination_id|some_flag
1 | 12      |  13          |  NULL
2 | 12      |  14          |  NULL
...

另一个表table_flag具有相同的行数和以下结构:

id|some_flag
1 | true
2 | false
...

我需要table_all table_flag的值设置some_flag。如果我发出这样的声明:

UPDATE table_all set some_flag = table_flag.some_flag 
from table_flag 
where table_all.id = table_flag.id

这需要几个小时,而且我需要经常做这个手术。这两个表按id排序,id是惟一的,并且这两个表都有id。对我来说,用< code>table_flag中的值设置< code>table_all中的< code>some_flag只是执行从< code>table_flag到< code>table_all的批量复制。有办法做到这一点吗?

共有3个答案

齐甫
2023-03-14

防止实际上不会改变任何东西但同样昂贵的“空更新”,因为Postgres无论如何都需要插入新的行版本。

UPDATE table_all a
SET    some_flag = f.some_flag 
FROM   table_flag f
WHERE  a.id = f.id
AND    a.some_flag IS DISTINCT FROM f.some_flag;

对于可以为NULL的列,使用< code >与不同。< br >对于定义为NOT NULL的列< code >

此外,在数据库表中没有“顺序”,你有一个基本的误解。索引会有很大帮助,但是当您必须处理所有行时就没有用了。

您可能应该更改您的工作流程,以便能够选择要更新的几行。您当前的方法效率极低,即使使用了改进的查询。

陈飞
2023-03-14

如果标志确实是布尔列,我建议使用默认值和子查询的组合,例如:

UPDATE table_all SET some_flag = True WHERE id IN (SELECT id FROM table_flag WHERE some_flag=True)

编辑:删除语句“table_all上的(id,some_flag)上的非聚集索引可能会有所帮助。”因为正如Andrew所指出的,索引布尔列不是一个好主意。

钱京
2023-03-14

如果您的更新是增量的(例如,主表中的大多数标志都不为空),请使用以下查询:

update table_all 
set some_flag = table_flag.some_flag 
from table_flag 
where 
    table_all.id = table_flag.id
    and (table_all.some_flag isnull
        or table_all.some_flag <> table_flag.some_flag);

如果主表中的所有(或主要部分)标志都为 null,则可以尝试使用游标:

do $$
declare  
    cur cursor for select id, some_flag from table_flag;
    rec record;
begin
    for rec in cur loop
        update table_all 
        set some_flag = rec.some_flag 
        where 
            table_all.id = rec.id
            and (table_all.some_flag isnull
                or table_all.some_flag <> rec.some_flag);
    end loop;
end $$;
 类似资料:
  • 问题内容: 我使用TablePlus(SQL客户端)将Postgres SQL文件导入到服务器,但是在插入新行后出现如下错误: SQLSTATE [23505]:唯一冲突:7错误:重复的键值违反了唯一约束\“ users_pkey \”详细信息:密钥(id)=(1)已存在 我知道它是由序列值0引起的,需要通过以下代码进行更新: 但是,如果我必须一一写入所有表序列(可能是数百个序列),则需要花费大量

  • 我导入PostgresSQL文件到我的服务器使用TablePlus(SQL客户端),但我插入新行后,我得到了这样的错误: SQLSTATE[23505]:唯一冲突:7错误:重复键值违反唯一约束\“users\u pkey\”详细信息:键(id)=(1)已存在 我知道它是由序列值为0引起的,需要通过下面的代码进行更新: 但是如果我必须一个接一个地写所有的表序列(可能是数百个序列),那就需要很多时间。

  • 我想用Django更新一个表-类似这样的原始SQL: 我的第一个结果是这样的——但这很恶心,不是吗? 有没有更优雅的方式?

  • 问题内容: 我正在使用Cloud Firestore,并且有一系列文档。对于集合中的每个文档,我想更新一个字段。 使用事务执行更新将效率低下,因为在更新数据时不需要读取任何数据。 批处理更新似乎是正确的方向,但是文档中没有包含一次更新多个文档的示例。参见此处:批量写入 问题答案: 如果您使用过Firebase数据库,则不可能原子地完全写入单个单独的位置,这就是为什么您必须使用批量写入的原因,这意味

  • 问题内容: 我有一个包含一千万行的表,需要与另一个表连接并更新所有数据。一小时要花费超过1个小时的时间,这使我的事务日志增加了10+ GB。是否有另一种方法可以增强此性能? 我相信,每次更新后,都会检查索引和约束并记录所有信息。有没有一种方法可以告诉SQL Server仅在更新完成后才检查约束并最小化记录更新操作? 我的查询如下。我已经修改了一些名称,以便于阅读。 编辑: 如注释中所述,表定义将类

  • 问题内容: 我试图: 根据搜索条件查找文档, 如果找到,请更新一些属性 如果没有插入带有某些属性的文档。 我正在使用,因为我也在执行单个插入操作。我想在一次操作中完成所有操作。 但是,它什么都不会导致为更新/向上插入操作插入任何内容。 这是插入文档: 这是最新资料: 这就是我试图更新/更新的方式: 为什么不更新/更新呢? 注意 那是使用水线ORM的JS代码,它也使用mongodb本机驱动程序。 问