欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

百万级数据批处理

程序员文章站 2022-06-04 09:02:30
...

问题来了,如果给你百万条数据要插入数据库,怎么处理?
for循环一条一条插入,搞一个存储过程,开线程池跑balabala….没敢去试,大概睡一觉回来还在执行。
百度了一下相关资料,原来要用jdbc批量操作。
总的来说,大概有三种方式:事务提交,批量操作,批量操作+事务提交。

批量操作+事务提交性能最佳,但是有两点要特别注意:
JDBC连接的url中要加rewriteBatchedStatements参数设为true是批量操作的前提
自动提交改为false:conn.setAutoCommit(false)

 private String url = "jdbc:mysql://localhost:3306/test?rewriteBatchedStatements=true";//记得参数设置为true
 private String user = "root";
 private String password = "123456";
 @Test
 public void Test(){
           Connection conn = null;
           PreparedStatement pstm =null;
           ResultSet rt = null;
           try {
             Class.forName("com.mysql.jdbc.Driver");
             conn = DriverManager.getConnection(url, user, password);        
             String sql = "INSERT INTO test(param1,param2,param3,param4) VALUES(?,?,?,?)";
             pstm = conn.prepareStatement(sql);//stm也可,pstm最佳
             conn.setAutoCommit(false);//自动提交改为false
             Long startTime = System.currentTimeMillis();
             for (int i = 1; i <= 1000000; i++) {
                     pstm.setInt(1, i);
                     pstm.setInt(2, i);
                     pstm.setString(3, "i");
                     pstm.setString(4, "i");
                     pstm.addBatch();
             }
             pstm.executeBatch();
             conn.commit();
             Long endTime = System.currentTimeMillis();
             System.out.println("用时:" + (endTime - startTime)); 
         } catch (Exception e) {
             e.printStackTrace();
             throw new RuntimeException(e);
         }finally{
             if(pstm!=null){
                 try {
                     pstm.close();
                 } catch (SQLException e) {
                     e.printStackTrace();
                     throw new RuntimeException(e);
                 }
             }
             if(conn!=null){
                 try {
                     conn.close();
                 } catch (SQLException e) {
                     e.printStackTrace();
                     throw new RuntimeException(e);
                 }
             }
         }
     }//end

测试用时百万级数据批处理

当然,也可以每5000条提交一次事务

for (int i = 1; i <= 1000000; i++) {
            pstm.setInt(1, i);
            pstm.setInt(2, i);
            pstm.setString(3, "i");
            pstm.setString(4, "i");
            pstm.addBatch();
            if(i%5000==0) {
                pstm.executeBatch();
                conn.commit();
                pstm.clearBatch();
            }
    }

测试用时百万级数据批处理

如果不适用批量处理只使用事务提交的话,建议每隔几千条提交一次事务,mysql提交一次超过10W条数据会出现数据丢失的情况,oracle更少。

相关标签: 批处理