【发布时间】: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