简体   繁体   English

Jooq批处理更新与MySql中的记录

[英]Jooq batch update with records in MySql

What is the proper way to do batch updates with JOOQ? 用JOOQ进行批处理更新的正确方法是什么?

I have the following: 我有以下内容:

public void updateScores(Map<String, Integer> teamScores) {
    writeContext().transaction(config -> {
        DSLContext dslContext = DSL.using(config);
        dslContext.batchUpdate(Maps.transformEntries(teamScores, (id, score) -> {
            TeamScoresRecord record = new TeamScoresRecord();
            record.setTeamId(id);
            record.setScore(score);
            return record;
        }).values()).execute();
    });
}

OR 要么

public void updateScores(Map<String, Integer> teamScores) {
    writeContext().transaction(config -> {
        DSLContext dslContext = DSL.using(config);
        dslContext.batchUpdate(
                dslContext.selectFrom(TEAM_SCORES)
                          .where(TEAM_SCORES.TEAM_ID.in(teamScores.keySet()))
                          .forUpdate()
                          .fetch()
                          .stream()
                          .peek(record -> record.setScore(teamScores.get(record.getTeamId())))
                          .collect(Collectors.toList())
        ).execute();
    });
}

Which of these is the recommended way to do batch updates? 建议使用以下哪种方法进行批处理更新?

This question is obviously very subjective and not easy to answer. 这个问题显然是非常主观的,而且不容易回答。 Here are a few observations: 以下是一些观察结果:

  • Even with using the batch API in jOOQ, you're running a lot of individual queries, which incurs quite a bit of client/server overhead. 即使在jOOQ中使用批处理API,您也会运行很多单独的查询,这会招致相当多的客户端/服务器开销。 This might be fine in your particular case, but it's usually not a bad idea to consider moving the entire logic into the database, eg by inserting your map in a temporary table and then merging the two data sets using a bulk UPDATE statement 在您的特定情况下,这可能很好,但是考虑将整个逻辑移至数据库中通常不是一个坏主意,例如,通过将地图插入临时表,然后使用批量UPDATE语句合并两个数据集
  • Both of your batches may cause deadlocks in the database, if two conflicting batches update the same records in a different order. 如果两个冲突的批次以不同的顺序更新相同的记录,则这两个批次都可能导致数据库死锁。 I'm not sure if this is an issue in your code, but you may want to make sure this can never happen. 我不确定这是否是您的代码中的问题,但是您可能要确保这永远不会发生。
  • The first approach will run one less query (the SELECT query, which might be quite expensive, depending on the size of the in-list). 第一种方法将运行较少的查询( SELECT查询,该查询可能很昂贵,具体取决于列表中的大小)。 Without the FOR UPDATE clause, however, the first approach might have a higher deadlocking risk. 但是,如果没有FOR UPDATE子句,第一种方法可能会具有更高的死锁风险。
  • The first approach will potentially run more update statements than necessary, eg for ID values that have been deleted in the meantime. 第一种方法可能会运行不必要的更新语句,例如,对于同时已删除的ID值。 The second approach prevents that from happening 第二种方法可以防止这种情况的发生

Now, I don't know MySQL well enough to know if a bulk update statement might be better here, ie a statement of the kind: 现在,我对MySQL的了解还不够,无法确定批量更新语句是否在这里更好,例如,以下类型的语句:

UPDATE team_scores
SET score = CASE id
  WHEN :id1 THEN :score1
  WHEN :id2 THEN :score2
  WHEN :id3 THEN :score3
  ...
END
WHERE id IN (:id1, :id2, :id3, ...)

Perhaps you could benchmark this approach and compare it to batching (or combine it with batching, eg bulk update 10 rows and batch all these bulk updates) 也许您可以对该方法进行基准测试并将其与批处理进行比较(或将其与批处理结合使用,例如批量更新10行并批处理所有这些批量更新)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM