百万级数据批处理
程序员文章站
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更少。
上一篇: 文本分析学习笔记