JDBC更新10W级以上数据性能优化

随笔缘由:

系统完成到一定程度,少不了要往数据库中添加大量数据进行性能测试。 我用程序做数据10W条,使用jdbc批更新的API,发现每次只能插入2W多条记录。 一番小小研究,觉得总结一下可能有些意义。

 

总结内容如下:

1:这是我出现问题的代码,插入10W条数据,10W次数据进行一次批处理,发现只能插入24464多条数据,程序也没有报错。

Connection con = (Connection) DriverManager.getConnection(url,user,password); 
  con.setAutoCommit( false ); 
  Long startTime = System.currentTimeMillis(); 
  PreparedStatement pst = (PreparedStatement) con.prepareStatement(sql.toString()); 
  for  ( int  i = 0 ; i < list.size(); i++) { 
      KIVResponseBean kivResponseBean=list.get(i);  
      pst.setString( 1 , kivResponseBean.getK()); 
      pst.setString( 2 , kivResponseBean.getI()); 
      pst.setInt( 3 , kivResponseBean.getV()); 
      pst.setInt( 4 , kivResponseBean.getD()); 
      pst.setString( 5 , kivResponseBean.getM()); 
      pst.setString( 6 , kivResponseBean.getR()); 
      pst.addBatch();    
}               
  pst.executeBatch();
  con.commit(); 
  Long endTime = System.currentTimeMillis(); 
  System.out.println( "用时:"  + (endTime - startTime)); 

2:在不使用批更新时,具体做法就是 不添加这句代码 con.setAutoCommit(false); 并且每次为SQL指定参数后就执行 pst.executeUpdate(); 提交数据;结果10W条记录插入成功,但是使用了 35833ms的时间消耗。

Class.forName( "oracle.jdbc.driver.OracleDriver" ); 
  Connection con = (Connection) DriverManager.getConnection(url,user,password); 
  Long startTime = System.currentTimeMillis(); 
  PreparedStatement pst = (PreparedStatement) con.prepareStatement(sql.toString()); 
  for  ( int  i = 0 ; i < list.size(); i++) { 
      KIVResponseBean kivResponseBean=list.get(i);  
      pst.setString( 1 , kivResponseBean.getK()); 
      pst.setString( 2 , kivResponseBean.getI()); 
      pst.setInt( 3 , kivResponseBean.getV()); 
      pst.setInt( 4 , kivResponseBean.getD()); 
      pst.setString( 5 , kivResponseBean.getM()); 
      pst.setString( 6 , kivResponseBean.getR()); 
      pst.executeUpdate();
}               
  Long endTime = System.currentTimeMillis(); 
  System.out.println( "用时:"  + (endTime - startTime));

 

3:使用批更新,并且制定没10000次提交一次更新,此时 使用时间 2980 ms ,10w条数据也批量添加成功,oracle对每次执行的批更新有限制,我在11g的环境下测试 在2W4K多,网上有朋友说在10g下 每次提交1W多数据就会报错。

Class.forName( "oracle.jdbc.driver.OracleDriver" ); 
Connection con = (Connection) DriverManager.getConnection(url,user,password); 
con.setAutoCommit( false ); 
Long startTime = System.currentTimeMillis(); 
PreparedStatement pst = (PreparedStatement) con.prepareStatement(sql.toString()); 
int  batchCount=list.size()/batchSize+ 1 ;
for ( int  batch= 0 ;batch<batchCount;batch++) {
     for  ( int  i = batch*batchSize; (i <(batch+ 1 )*batchSize)&&(i<list.size()); i++) { 
         KIVResponseBean kivResponseBean=list.get(i);  
         pst.setString( 1 , kivResponseBean.getK()); 
         pst.setString( 2 , kivResponseBean.getI()); 
         pst.setInt( 3 , kivResponseBean.getV()); 
         pst.setInt( 4 , kivResponseBean.getD()); 
         pst.setString( 5 , kivResponseBean.getM()); 
         pst.setString( 6 , kivResponseBean.getR()); 
         pst.addBatch();    
    }               
     pst.executeBatch();
     con.commit(); 
     pst.clearBatch();
}
Long endTime = System.currentTimeMillis(); 
System.out.println( "用时:"  + (endTime - startTime)); 

随笔缘由:

系统完成到一定程度,少不了要往数据库中添加大量数据进行性能测试。 我用程序做数据10W条,使用jdbc批更新的API,发现每次只能插入2W多条记录。 一番小小研究,觉得总结一下可能有些意义。

 

总结内容如下:

1:这是我出现问题的代码,插入10W条数据,10W次数据进行一次批处理,发现只能插入24464多条数据,程序也没有报错。

Connection con = (Connection) DriverManager.getConnection(url,user,password); 
  con.setAutoCommit( false ); 
  Long startTime = System.currentTimeMillis(); 
  PreparedStatement pst = (PreparedStatement) con.prepareStatement(sql.toString()); 
  for  ( int  i = 0 ; i < list.size(); i++) { 
      KIVResponseBean kivResponseBean=list.get(i);  
      pst.setString( 1 , kivResponseBean.getK()); 
      pst.setString( 2 , kivResponseBean.getI()); 
      pst.setInt( 3 , kivResponseBean.getV()); 
      pst.setInt( 4 , kivResponseBean.getD()); 
      pst.setString( 5 , kivResponseBean.getM()); 
      pst.setString( 6 , kivResponseBean.getR()); 
      pst.addBatch();    
}               
  pst.executeBatch();
  con.commit(); 
  Long endTime = System.currentTimeMillis(); 
  System.out.println( "用时:"  + (endTime - startTime)); 

2:在不使用批更新时,具体做法就是 不添加这句代码 con.setAutoCommit(false); 并且每次为SQL指定参数后就执行 pst.executeUpdate(); 提交数据;结果10W条记录插入成功,但是使用了 35833ms的时间消耗。

Class.forName( "oracle.jdbc.driver.OracleDriver" ); 
  Connection con = (Connection) DriverManager.getConnection(url,user,password); 
  Long startTime = System.currentTimeMillis(); 
  PreparedStatement pst = (PreparedStatement) con.prepareStatement(sql.toString()); 
  for  ( int  i = 0 ; i < list.size(); i++) { 
      KIVResponseBean kivResponseBean=list.get(i);  
      pst.setString( 1 , kivResponseBean.getK()); 
      pst.setString( 2 , kivResponseBean.getI()); 
      pst.setInt( 3 , kivResponseBean.getV()); 
      pst.setInt( 4 , kivResponseBean.getD()); 
      pst.setString( 5 , kivResponseBean.getM()); 
      pst.setString( 6 , kivResponseBean.getR()); 
      pst.executeUpdate();
}               
  Long endTime = System.currentTimeMillis(); 
  System.out.println( "用时:"  + (endTime - startTime));

 

3:使用批更新,并且制定没10000次提交一次更新,此时 使用时间 2980 ms ,10w条数据也批量添加成功,oracle对每次执行的批更新有限制,我在11g的环境下测试 在2W4K多,网上有朋友说在10g下 每次提交1W多数据就会报错。

Class.forName( "oracle.jdbc.driver.OracleDriver" ); 
Connection con = (Connection) DriverManager.getConnection(url,user,password); 
con.setAutoCommit( false ); 
Long startTime = System.currentTimeMillis(); 
PreparedStatement pst = (PreparedStatement) con.prepareStatement(sql.toString()); 
int  batchCount=list.size()/batchSize+ 1 ;
for ( int  batch= 0 ;batch<batchCount;batch++) {
     for  ( int  i = batch*batchSize; (i <(batch+ 1 )*batchSize)&&(i<list.size()); i++) { 
         KIVResponseBean kivResponseBean=list.get(i);  
         pst.setString( 1 , kivResponseBean.getK()); 
         pst.setString( 2 , kivResponseBean.getI()); 
         pst.setInt( 3 , kivResponseBean.getV()); 
         pst.setInt( 4 , kivResponseBean.getD()); 
         pst.setString( 5 , kivResponseBean.getM()); 
         pst.setString( 6 , kivResponseBean.getR()); 
         pst.addBatch();    
    }               
     pst.executeBatch();
     con.commit(); 
     pst.clearBatch();
}
Long endTime = System.currentTimeMillis(); 
System.out.println( "用时:"  + (endTime - startTime)); 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值