JOOQ批处理语句中的绑定调用数是否有上限?

时间:2016-03-10 17:54:33

标签: 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. 似乎可以在执行.bind()后再次致电.execute().execute()会清除之前绑定的值吗?
  4. 澄清最后一个问题:执行以下代码后......

    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
    

    不幸的是,Javadocthe documentation都没有讨论这种特殊的使用模式。

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

1 个答案:

答案 0 :(得分:1)

此答案自jOOQ 3.7起有效

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

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

  
      
  1. 如果是,那么限制取决于什么?
  2.   

有几件事:

  • 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以插入加载程序表,例如:使用Oracle's SQL*Loader。一旦您插入了所有数据,您就可以将其移动到真正的表格"使用PL/SQL's FORALL statement,这是PL / SQL的JDBC批处理语句版本。这种方法将执行您使用JDBC所做的任何事情。

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

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