我们在插入时使用批处理语句如下:
BatchBindStep batch = create.batch(create
.insertInto(PERSON, ID, NAME)
.values((Integer) null, null));
for (Person p : peopleToInsert) {
batch.bind(p.getId(), p.getName());
}
batch.execute();
这在过去插入数千个对象时效果很好。然而,它提出了几个问题:
- 批处理的
.bind()
调用次数是否有上限? - 如果是这样,限制取决于什么?
- 似乎可以在执行完
.execute()
后再次调用.bind()
。.execute()
会清除之前绑定(bind)的值吗?
澄清最后一个问题:执行以下代码后...
BatchBindStep batch = create.batch(create
.insertInto(PERSON, ID, NAME)
.values((Integer) null, null));
batch.bind(1, "A");
batch.bind(2, "B");
batch.extecute();
batch.bind(3, "C");
batch.bind(4, "D");
batch.execute();
我应该期待哪个结果?
a) b)
ID NAME ID NAME
------- -------
1 A 1 A
2 B 2 B
3 C 1 A
4 D 2 B
3 C
4 D
不幸的是,Javadoc 都不是也不the documentation讨论这个特定的使用模式。
(我问这个特定的问题是因为如果我 .execute()
每 1000 次绑定(bind)左右以避免上述限制,我需要知道我是否可以重用 batch
多个 .execute()
调用的对象。)
最佳答案
这个答案从 jOOQ 3.7 开始有效
- Is there an upper limit to the number of .bind() calls for a batch?
在 jOOQ 中没有,但你的 JDBC 驱动程序/数据库服务器可能有这样的限制。
- If so, what does the limit depend on?
几件事:
- jOOQ 为所有绑定(bind)变量保留一个中间缓冲区,并将它们一次性全部绑定(bind)到 JDBC 批处理语句。因此,您的客户端内存也可能会施加上限。但是 jOOQ 本身没有任何限制。
您的 JDBC 驱动程序可能知道此类限制 (see also this article on how jOOQ handles limits in non-batch statements)。已知的限制是:
- SQLite:每条语句 999 个绑定(bind)变量
- Ingres 10.1.0:每条语句 1024 个绑定(bind)变量
- Sybase ASE 15.5:每条语句 2000 个绑定(bind)变量
- SQL Server 2008:每条语句 2100 个绑定(bind)变量
我不知道 Oracle 中有任何此类限制,但可能有。
插入大量数据时,批量大小并不是您唯一应该调整的东西。还有:
- 批量大小,即每个语句插入的行数
- 批量大小,即每批发送到服务器的语句数
- 提交大小,即单个事务中提交的批处理数
调整您的插入归结为调整以上所有内容。 jOOQ 附带一个专用的导入 API,您可以在其中调整以上所有内容:http://www.jooq.org/doc/latest/manual/sql-execution/importing
您还应该考虑绕过 SQL 以插入加载程序表,例如使用 Oracle's SQL*Loader .插入所有数据后,您可以使用 PL/SQL's
FORALL
statement 将其移动到“真实表” ,这是 JDBC 批处理语句的 PL/SQL 版本。这种方法将胜过您使用 JDBC 执行的任何操作。
- It seems to be possible to call .bind() again after having executed .execute(). Will .execute() clear previously bound values?
目前,execute()
不会清除绑定(bind)值。您需要改为创建一个新语句。这不太可能改变,因为 future 的 jOOQ 版本将支持其 API 设计的不变性。
关于java - JOOQ批处理语句中的绑定(bind)调用次数是否有上限?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35923816/