hya*_*hya 5 java database postgresql bulkinsert jooq
我目前正在尝试批量插入许多记录(约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);
}
}
Run Code Online (Sandbox Code Playgroud)
我可以这样做(因为Jooq在内部做同样的事情):
records.forEach(UpdatableRecord::insert);
Run Code Online (Sandbox Code Playgroud)
代替:
jooq.batchInsert(records).execute();
Run Code Online (Sandbox Code Playgroud)
如何告诉Jooq以批处理方式创建新记录?我应该将记录转换为绑定查询,然后调用batchInsert吗?有任何想法吗?;)
jOOQ 为DSLContext.batchInsert()每组连续记录创建一个 JDBC 批处理语句,这些语句具有相同的生成 SQL 字符串(不幸的是,Javadoc 没有正式定义这一点)。
当您的记录如下所示时,这可能会变成一个问题:
+------+--------+--------+
| COL1 | COL2 | COL3 |
+------+--------+--------+
| 1* | {null} | {null} |
| 2* | B* | {null} |
| 3* | {null} | C* |
| 4* | D* | D* |
+------+--------+--------+
Run Code Online (Sandbox Code Playgroud)
..因为在这种情况下,生成的 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 (?, ?, ?);
Run Code Online (Sandbox Code Playgroud)
这种默认行为的原因是这是保证......行为的唯一方法DEFAULT。正如在 SQL 中一样DEFAULT。我在这里给出了这种行为的理由。
考虑到这一点,并且由于每个连续的 SQL 字符串都不同,不幸的是,插入并没有按照您的预期作为单个批次进行批处理。
true强制所有INSERT语句相同的一种方法是将每个单独记录的所有已更改标志设置为true:
for (Record r : records)
r.changed(true);
Run Code Online (Sandbox Code Playgroud)
现在,所有 SQL 字符串都将相同。
LoaderAPI您可以导入数据(并在此处指定批量大小),而不是批处理。有关详细信息,请参阅手册中有关导入记录的部分:
https://www.jooq.org/doc/latest/manual/sql-execution/importing/importing-records
您batchInsert()使用 的便利性在使用 时有效TableRecords。当然,您可以INSERT手动生成语句并使用 jOOQ 的批处理语句 API 对各个绑定变量进行批处理:
https://www.jooq.org/doc/latest/manual/sql-execution/batch-execution
关于该 API 和类似的 API 有几个悬而未决的问题DSLContext.batchInsert()。为每个单独的记录生成 SQL 字符串的客户端算法效率低下,并且将来可能会changed()直接依赖于标志而更改。一些相关问题:
| 归档时间: |
|
| 查看次数: |
4869 次 |
| 最近记录: |