3

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

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. .bind()执行后似乎可以再次调用.execute()。会.execute()清除以前绑定的值吗?

澄清最后一个问题:执行以下代码后......

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文档都没有讨论这种特定的使用模式。

(我问这个特定的问题是因为如果我.execute()每 1000 次绑定左右以避免上述限制,我需要知道我是否可以将batch对象重用于多个.execute()调用。)

4

1 回答 1

1

此答案自 jOOQ 3.7 起有效

  1. 批处理的 .bind() 调用数量是否有上限?

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

  1. 如果是这样,限制取决于什么?

几件事:

  • jOOQ 为所有绑定变量保留一个中间缓冲区,并将它们一次性绑定到 JDBC 批处理语句。因此,您的客户端内存也可能会施加上限。但是 jOOQ 本身没有任何限制。
  • 您的 JDBC 驱动程序可能知道这些限制(另请参阅这篇关于 jOOQ 如何处理非批处理语句中的限制的文章)。已知的限制是:

    • SQLite:每条语句 999 个绑定变量
    • Ingres 10.1.0:每个语句 1024 个绑定变量
    • Sybase ASE 15.5:每条语句 2000 个绑定变量
    • SQL Server 2008:每条语句 2100 个绑定变量

    我不知道 Oracle 中有任何此类限制,但可能有。

  • 在插入大量数据时,批量大小并不是您应该调整的唯一因素。还有:

    • 批量大小,即每条语句插入的行数
    • 批量大小,即每批发送到服务器的语句数
    • 提交大小,即单个事务中提交的批次数

    调整插入归结为调整以上所有内容。jOOQ 附带一个专用的导入 API,您可以在其中调整上述所有内容:http: //www.jooq.org/doc/latest/manual/sql-execution/importing

  • 您还应该考虑绕过 SQL 来插入加载器表,例如使用Oracle 的 SQL*Loader。插入所有数据后,您可以使用PL/SQL 的FORALLstatement将其移动到“真实表” ,这是 PL/SQL 版本的 JDBC 批处理语句。这种方法将胜过您对 JDBC 所做的任何事情。

  1. 执行 .execute() 后似乎可以再次调用 .bind()。.execute() 会清除以前绑定的值吗?

目前,execute()不会清除绑定值。您需要创建一个新语句。这不太可能改变,因为未来的 jOOQ 版本将在其 API 设计中支持不变性。

于 2016-03-11T09:56:15.263 回答