当前位置: 首页 > 面试题库 >

Postgresql批处理插入或忽略

臧兴学
2023-03-14
问题内容

我有责任将我们的代码从sqlite切换到postgres。我遇到麻烦的查询之一复制到下面。

INSERT INTO group_phones(group_id, phone_name)
SELECT g.id, p.name 
FROM phones AS p, groups as g
WHERE g.id IN ($add_groups) AND p.name IN ($phones);

当有重复的记录时,就会出现此问题。在此表中,两个值的组合必须唯一。我在其他地方使用了一些plpgsql函数来执行更新或插入操作,但是在这种情况下,我可以一次执行多个插入操作。我不确定如何为此编写存储的例程。感谢您提供的所有sql专家的所有帮助!


问题答案:

3个 挑战。

  1. 您的查询在表和之间没有 JOIN 条件,这实际上使其受到限制-您很可能不希望这样做。即,每个合格的电话都与合格的每个组结合在一起。如果您有100部电话和100个群组,那么已经是10,000个组合。phones``groups``CROSS JOIN

  2. 插入以下内容的 不同 组合(group_id, phone_name)

  3. 避免插入table中 已经存在的group_phones

所有考虑到的事物可能看起来像这样:

INSERT INTO group_phones(group_id, phone_name)
SELECT i.id, i.name
FROM  (
    SELECT **DISTINCT** g.id, p.name -- get distinct combinations
    FROM   phones p
    JOIN   groups g ON **??how are p & g connected??**
    WHERE  g.id IN ($add_groups)
    AND    p.name IN ($phones)
    ) i
**LEFT   JOIN** group_phones gp ON (gp.group_id, gp.phone_name) = (i.id, i.name)
**WHERE  gp.group_id IS NULL**  -- avoid duping existing rows

并发

这种形式将并发写入操作的竞争条件的可能性降到最低。 如果 您的表具有 较大的并发写入
负载,则可能要排他地锁定表或使用可序列化的事务隔离,这可以防止在约束验证(行)之间的微小时隙中并发事务更改行的可能性极小不存在)和查询中的写操作。

BEGIN ISOLATION LEVEL SERIALIZABLE;
INSERT ...
COMMIT;

如果事务因序列化错误而回滚,请准备好重复该事务。

通常,尽管如此,您甚至都不需要理会这些。

表现

LEFT JOIN tbl ON right_col = left_col WHERE right_col IS NULL

通常是最快的方法,在右表中有不同的列。如果您的栏中有重复项(特别是如果有很多),

WHERE NOT EXISTS (SELECT 1 FROM tbl WHERE right_col = left_col)

可能更快,因为一旦找到第一行它就可以停止扫描。

您也可以使用IN@dezso演示的,但是在PostgreSQL中通常较慢。



 类似资料:
  • 问题内容: 有没有解决方案通过hibernate在分区后的PostgreSQL表中批量插入?目前我遇到这样的错误… 我已经找到此链接http://lists.jboss.org/pipermail/hibernate- dev/2007-October/002771.html, 但我在网上找不到任何地方可以解决此问题或如何解决该问题 问题答案: 您可能想通过设置hibernate.jdbc.fac

  • 问题内容: 我有一个dao,它基本上使用hibernate将记录插入到一​​个表中,该dao用标记为注释,并且我有一个服务,该服务会生成其他一些东西,然后调用我的dao。我的服务也标注了使用。 我叫服务循环。我在dao上的插入内容是否可以批量或一个接一个地工作?我如何确定它们可以批量工作?hibernateTransaction Manager是否管理批处理插入? 我正在使用Oracle DB。

  • 我的批处理插入器有奇怪的问题。批处理插入器工作良好,但当我从该位置启动服务器时,CYPHER无法筛选属性。 Query返回所有节点。但当我尝试基于任何属性筛选它时,它不会返回任何行。查询不返回任何内容。 如果我运行run SET命令来更新属性,那么我就能够很好地筛选它。看起来像是索引问题,但无法准确计算。

  • 问题内容: 我需要将几亿条记录插入mysql db。我要一次插入一百万个。请在下面查看我的代码。它似乎很慢。有什么方法可以优化它吗? 问题答案: 我在mysql中遇到类似的性能问题,并通过在连接URL中设置useServerPrepStmts和rewriteBatchedStatements属性来解决。

  • 在我的项目中配置了以下内容: 加载文件时,我有重复的记录,但因为我配置了在下,Spring batch不应回滚记录,但仍将回滚记录。如果我从列表中删除,那么它将抛出异常。我们正在使用Spring批处理版本: 不希望回滚记录,但会回滚记录。

  • Cassaforte具有插入批处理功能,可一次性将多行插入到cassandra CQL表中。 我最近切换到Alia,我想知道它是否提供相同的功能?我不能立即在留档中看到任何内容,并且(hayt/value…)似乎一次只支持单行插入。