关于 addBatch(String) 的注意事项

Posted

技术标签:

【中文标题】关于 addBatch(String) 的注意事项【英文标题】:Considerations regarding addBatch(String) 【发布时间】:2012-07-03 10:47:54 【问题描述】:

PreparedStatementaddBatch() 方法旁边,Statement 类中还有一个addBatch(String) 方法。

我想处理一系列不同的 sql 语句,并且正在寻找一些关于 addBatch(String) 在性能方面的含义的说明。使用这种方法是否安全(且快速),还是在 Java 中将类似的 sql 语句分组并分组执行是否更好?

【问题讨论】:

【参考方案1】:

批处理允许您将相关的 SQL 语句分组到一个批处理中,并通过一次调用数据库来提交它们。

当您一次向数据库发送多个 SQL 语句时,可以减少通信开销,从而提高性能。

addBatch(String sql)定义在接口java.sql.Statement中,addBatch()定义在java.sql.PreparedStatementextends Statement的子接口之一。 (其他是java.sql.CallableStatement

根据JAVA Doc

addbatch(String sql) 方法不能在 PreparedStatementCallableStatement 和 sql 上调用 - 通常这是 SQL INSERTUPDATE 语句。

如果您想要批量插入或批量更新操作,首选addBatch()

批处理执行的阻塞因素很少

DB make/version.
JDBC driver make/version.

例如:如果您使用的是 mysql,请使用最新的驱动程序将 rewriteBatchedStatements=true 添加到您的连接字符串中,以使 statement.addBatch() 实际创建批量插入。

另外,您应该确保自动提交是错误的。维护一个计数器,当 Java 中的可用堆内存受到限制时,该计数器可以到达该计数器 executeBatch。

例子:

conn.setAutoCommit(false);  
PreparedStatement pStmt = conn.prepareStatement("INSERT INTO mytable (field1,field2) VALUES (?,?)");

for all values:
  pStmt.setString(1,val1);
  pStmt.setString(2,val2);
  pStmt.addBatch();    
  if ( i % 1000 == 0)   
            pstmt.executeBatch();// Execute every 1000 items  
   
pstmt.executeBatch(); 
conn.commit(); 

【讨论】:

恐怕这不是答案,我正在寻找。我知道, addBatch() 是如何工作的,并且您关于 addBatch(String) 无法从 PreparedStatement 访问的声明是不正确的。我想知道,addBatch(String) 是否为逐个执行语句提供了任何优势(性能方面)。 @Jonathan:请参阅 Java Doc 的链接“addBatch(String) is not access from PreparedStatement is not correct.”来自答案。另外,考虑到这一事实,它写道 addBatch() 在性能方面具有优势。 这个i 变量从何而来?我们可以从语句中得到它吗? @sebnukem:我已经举了一个像 psudocode 这样的例子。 “i”表示一个增量变量,用于打破循环并提交记录。

以上是关于关于 addBatch(String) 的注意事项的主要内容,如果未能解决你的问题,请参考以下文章

statement.addBatch() /statement.executeBatch() 返回结果集?

java中的PreparedStatement.addBatch有啥限制吗?

使用 addBatch 和 executeBatch 时是不是必须使用相同的 prepareCall?为啥?

JDBC批量插入数据优化,使用addBatch和executeBatch

JDBC批量插入数据优化,使用addBatch和executeBatch

JDBC批量插入数据优化,使用addBatch和executeBatch