百万级数据批处理

问题来了,如果给你百万条数据要插入数据库,怎么处理?
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更少。

猜你喜欢

转载自blog.csdn.net/qq_33157669/article/details/81666461