【问题标题】:jOOQ batch insertion inconsistencyjOOQ 批量插入不一致
【发布时间】:2021-05-23 21:29:12
【问题描述】:

在 jOOQ (v3.14.4) 中使用批量插入时,我注意到在查看 PostgreSQL (v12.6) 日志时存在一些不一致之处。 在执行context.batch(<query>).bind(<1st record>).bind(<2nd record>)...bind(<nth record>).execute() 时,日志显示记录实际上是一一插入的,而不是一次性插入的。 在执行context.insert(<fields>).values(<1st record>).values(<2nd record>)...values(<nth record>) 时,根据 postgres 日志判断,实际上一口气插入了所有内容。 是 jOOQ 本身的错误还是我错误地使用了 batch(...) 功能?

这里有 2 个代码 sn-ps 应该做同样的事情,但实际上,第一个代码一个接一个地插入记录,而第二个代码实际上是批量插入。

    public void batchInsertEdges(List<EdgesRecord> edges) {
        Query batchQuery = context.insertInto(Edges.EDGES,
                Edges.EDGES.SOURCE_ID, Edges.EDGES.TARGET_ID, Edges.EDGES.CALL_SITES,
                Edges.EDGES.METADATA)
                .values((Long) null, (Long) null, (CallSiteRecord[]) null, (JSONB) null)
                .onConflictOnConstraint(Keys.UNIQUE_SOURCE_TARGET).doUpdate()
                .set(Edges.EDGES.CALL_SITES, Edges.EDGES.as("excluded").CALL_SITES)
                .set(Edges.EDGES.METADATA, field("coalesce(edges.metadata, '{}'::jsonb) || excluded.metadata", JSONB.class));
        var batchBind = context.batch(batchQuery);
        for (var edge : edges) {
            batchBind = batchBind.bind(edge.getSourceId(), edge.getTargetId(),
                    edge.getCallSites(), edge.getMetadata());
        }
        batchBind.execute();
    }
    public void batchInsertEdges(List<EdgesRecord> edges) {
        var insert = context.insertInto(Edges.EDGES,
                Edges.EDGES.SOURCE_ID, Edges.EDGES.TARGET_ID, Edges.EDGES.CALL_SITES, Edges.EDGES.METADATA);
        for (var edge : edges) {
            insert = insert.values(edge.getSourceId(), edge.getTargetId(), edge.getCallSites(), edge.getMetadata());
        }
        insert.onConflictOnConstraint(Keys.UNIQUE_SOURCE_TARGET).doUpdate()
                .set(Edges.EDGES.CALL_SITES, Edges.EDGES.as("excluded").CALL_SITES)
                .set(Edges.EDGES.METADATA, field("coalesce(edges.metadata, '{}'::jsonb) || excluded.metadata", JSONB.class))
                .execute();
    }

我希望能得到一些帮助来弄清楚为什么第一个代码 sn-p 不能按预期工作,而第二个代码可以。谢谢!

【问题讨论】:

    标签: java postgresql jooq


    【解决方案1】:

    “批处理”(如 JDBC 批处理)和“批量处理”(如许多 RDBMS 所说的“批量更新”)之间存在区别。

    This page of the manual about data import explains the difference.

    • 批量大小:在一条 SQL 语句中发送到服务器的行数。
    • 批处理大小:一个 JDBC 语句批处理中发送到服务器的语句数。

    这些是根本不同的东西。两者都有助于提高性能。批量数据处理通过帮助 RDBMS 优化资源分配算法来实现这一点,因为它知道它将插入 10 条记录。批量数据处理通过减少客户端和服务器之间的往返次数来实现。这两种方法是否对任何给定的 RDBMS 产生重大影响显然是特定于供应商的。

    换句话说,您的两种方法都按预期工作。

    【讨论】:

      猜你喜欢
      • 2018-08-13
      • 2021-03-27
      • 2020-05-22
      • 2017-12-29
      • 2020-03-18
      • 2013-07-02
      • 2015-09-02
      • 2021-01-20
      • 2020-08-29
      相关资源
      最近更新 更多