批量插入mysql的使用場景
在sqlServer里有BulkInsert,可以高效的插入數據。在Java中,我們常用的數據庫是mysql,mysql并沒有提供類似的功能。我們現在常用的操作數據庫的技術是mybatis,但是,如果使用mybatis來大批量插入數據,比如一次插入50萬行數據,這樣會特別慢,速度是無法接受的。
查了一些資料,發現直接使用JDBC批量插入效率不錯,寫一些筆記備忘。
樣例代碼
public void batchInsertGeneratePlanOrder(List<MRPRequirement> requirementList, Long planParamId, String creator) throws Exception {
Connection conn = DriverManager.getConnection(dbUrl, user, password);
//將自動提交關閉
conn.setAutoCommit(false);
PreparedStatement preparedStatement = null;
if (preparedStatement != null) {
preparedStatement.clearParameters();
preparedStatement.clearBatch();
}
String planOrderSql = ".........";
preparedStatement = conn.prepareStatement(planOrderSql);
for (int requirementItemIndex = 0; requirementItemIndex < requirementList.size(); requirementItemIndex++) {
//將sql語句中的參數替換為實際的值
handleParameters(preparedStatement, requirementList.get(requirementItemIndex), planParamId, creator);
preparedStatement.addBatch();
// 分段提交
if (requirementItemIndex % 20000 == 0 && requirementItemIndex != 0) {
preparedStatement.executeBatch();
preparedStatement.clearBatch();
}
}
// 提交事務
preparedStatement.executeBatch();
conn.commit();
preparedStatement.close();
conn.close();
}
涉及到mysql的一些參數
- bulk_insert_buffer_size=120M 或者更大
- 將insert語句的長度設為最大。Max_allowed_packet=1M
- Net_buffer_length=512k
- mysql的鏈接中加入參數:&rewriteBatchedStatements=true
參考鏈接
http://www.lxweimin.com/p/04d3d235cb9f
https://yq.aliyun.com/articles/378296
https://blog.csdn.net/u011277123/article/details/61914773/
http://www.mamicode.com/info-detail-1778588.html
https://blog.csdn.net/zhangjingao/article/details/80331415
http://www.lxweimin.com/p/610dac44fb36
https://blog.csdn.net/tolcf/article/details/52102849
http://www.lxweimin.com/p/04d3d235cb9f
備注
分段提交的取模值不一定是20000,我這邊是嘗試了插入50萬數據,不同的設置值的對比如下:
批次數量1000 53s
批次數量10000 44s
批次數量500 45s
批次數量20000 40s
暫時選擇了每批20000條sql來提交。