gpt4 book ai didi

java - Jooq批量记录插入

转载 作者:搜寻专家 更新时间:2023-10-31 20:17:25 32 4
gpt4 key购买 nike

我目前正在尝试批量插入许多记录(~2000),而 Jooq 的 batchInsert 没有按照我的意愿进行。

我正在将 POJO 转换为 UpdatableRecords,然后执行 batchInsert,它为每条记录执行插入。所以 Jooq 对每个批量插入执行约 2000 次查询,这会降低数据库性能。

它正在执行这段代码(jooq 的批量插入):

for (int i = 0; i < records.length; i++) {
Configuration previous = ((AttachableInternal) records[i]).configuration();

try {
records[i].attach(local);
executeAction(i);
}
catch (QueryCollectorSignal e) {
Query query = e.getQuery();
String sql = e.getSQL();

// Aggregate executable queries by identical SQL
if (query.isExecutable()) {
List<Query> list = queries.get(sql);

if (list == null) {
list = new ArrayList<Query>();
queries.put(sql, list);
}

list.add(query);
}
}
finally {
records[i].attach(previous);
}
}

我可以这样做(因为 Jooq 在内部做同样的事情):

records.forEach(UpdatableRecord::insert);

代替:

jooq.batchInsert(records).execute();

我如何告诉 Jooq 以批处理模式创建新记录?我应该将记录转换为绑定(bind)查询然后调用 batchInsert 吗?有任何想法吗? ;)

最佳答案

jOOQ 的 DSLContext.batchInsert()为每组具有相同生成的 SQL 字符串的连续记录创建一个 JDBC 批处理语句(不幸的是,Javadoc 没有正式定义它)。

当您的记录如下所示时,这可能会变成一个问题:

+------+--------+--------+
| COL1 | COL2 | COL3 |
+------+--------+--------+
| 1* | {null} | {null} |
| 2* | B* | {null} |
| 3* | {null} | C* |
| 4* | D* | D* |
+------+--------+--------+

.. 因为在那种情况下,生成的 SQL 字符串将如下所示:

INSERT INTO t (col1) VALUES (?);
INSERT INTO t (col1, col2) VALUES (?, ?);
INSERT INTO t (col1, col3) VALUES (?, ?);
INSERT INTO t (col1, col2, col3) VALUES (?, ?, ?);

此默认行为的原因是,这是保证 ... DEFAULT 行为的唯一方法。与在 SQL DEFAULT 中一样。 I gave a rationale of this behaviour here .

考虑到这一点,并且由于每个连续的 SQL 字符串都不同,很遗憾,插入操作并未按您的预期作为单个批处理进行批处理。

解决方案 1:确保所有更改的标志都是 true

强制所有 INSERT 语句相同的一种方法是将每个 individula 记录的所有更改标志设置为 true:

for (Record r : records)
r.changed(true);

现在,所有 SQL 字符串都将相同。

解决方案 2:使用 Loader API

您可以导入数据(并在那里指定批大小)而不是批处理。有关详细信息,请参阅手册中有关导入记录的部分:

https://www.jooq.org/doc/latest/manual/sql-execution/importing/importing-records

解决方案 3:改用批处理语句

您对 batchInsert() 的使用很方便,在使用 TableRecords 时也很方便。但当然,您可以手动生成一个 INSERT 语句,并使用 jOOQ 的批处理语句 API 对各个绑定(bind)变量进行批处理:

https://www.jooq.org/doc/latest/manual/sql-execution/batch-execution

性能说明

DSLContext.batchInsert() 和类似的 API 有几个 Unresolved 问题。为每个单独的记录生成 SQL 字符串的客户端算法效率低下,将来可能会更改,直接依赖于 changed() 标志。一些相关问题:

关于java - Jooq批量记录插入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45274242/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com