java - JOOQ批处理语句中的绑定(bind)调用次数是否有上限?

标签 java jooq batch-insert

我们在插入时使用批处理语句如下:

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();

这在过去插入数千个对象时效果很好。然而,它提出了几个问题:

  1. 批处理的.bind() 调用次数是否有上限?
  2. 如果是这样,限制取决于什么?
  3. 似乎可以在执行完.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 开始有效

  1. Is there an upper limit to the number of .bind() calls for a batch?

在 jOOQ 中没有,但你的 JDBC 驱动程序/数据库服务器可能有这样的限制。

  1. 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 执行的任何操作。

  1. 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/

相关文章:

java - 正则表达式或 Java 将某些区域转换为较低的字符串

java - 如何在 fragment 中启用操作栏选项卡?

Java/Spring JDBC : Batch Insert into 2 Tables: Obtain FK ID from 1st Batch Insert Required for 2nd Table

java - 批量插入和 Apache DBUtils

java - 批量插入时出现 TemporaryFailureException

java - 使用 == 检查对象引用相等性(在 Java 中)

java - JDBC - 在查询中重用绑定(bind)变量

java - utf8_unicode_ci 字符串插入错误?

java - 如何使用 JOOQ 从模板和参数占位符生成 sql?

postgresql - JOOQ 和字段值 : BigDecimal to Int