JOOQ批处理语句中的绑定调用次数是否有上限?
Is there an upper limit to the number of bind calls in a JOOQ batch statement?
我们在插入时使用批处理语句如下:
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()
会清除之前绑定的值吗?
澄清最后一个问题:执行以下代码后...
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 nor the documentation 都没有讨论这个特定的使用模式。
(我问这个特定的问题是因为如果我 .execute()
每 1000 次绑定左右以避免上述限制,我需要知道我是否可以将 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 为所有绑定变量保留一个中间缓冲区,并将它们一次性绑定到 JDBC 批处理语句。因此,您的客户端内存也可能会施加上限。但是jOOQ本身没有任何限制。
您的 JDBC 驱动程序可能知道这样的限制 (see also this article on how jOOQ handles limits in non-batch statements)。已知限制是:
- 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 以插入加载程序 table,例如使用 Oracle's SQL*Loader. Once you've inserted all data, you can move it to the "real table" using PL/SQL's FORALL
statement,这是 PL/SQL 版本的 JDBC 批处理语句。这种方法将执行您使用 JDBC.
执行的任何操作
- It seems to be possible to call .bind() again after having executed .execute(). Will .execute() clear previously bound values?
目前,execute()
不会清除绑定值。您需要改为创建一个新语句。这不太可能改变,因为未来的 jOOQ 版本将在其 API 设计中支持不变性。
我们在插入时使用批处理语句如下:
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()
会清除之前绑定的值吗?
澄清最后一个问题:执行以下代码后...
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 nor the documentation 都没有讨论这个特定的使用模式。
(我问这个特定的问题是因为如果我 .execute()
每 1000 次绑定左右以避免上述限制,我需要知道我是否可以将 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 为所有绑定变量保留一个中间缓冲区,并将它们一次性绑定到 JDBC 批处理语句。因此,您的客户端内存也可能会施加上限。但是jOOQ本身没有任何限制。
您的 JDBC 驱动程序可能知道这样的限制 (see also this article on how jOOQ handles limits in non-batch statements)。已知限制是:
- 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 以插入加载程序 table,例如使用 Oracle's SQL*Loader. Once you've inserted all data, you can move it to the "real table" using PL/SQL's
FORALL
statement,这是 PL/SQL 版本的 JDBC 批处理语句。这种方法将执行您使用 JDBC. 执行的任何操作
- It seems to be possible to call .bind() again after having executed .execute(). Will .execute() clear previously bound values?
目前,execute()
不会清除绑定值。您需要改为创建一个新语句。这不太可能改变,因为未来的 jOOQ 版本将在其 API 设计中支持不变性。