mysql批量插入優化
這段時間一直在參與產品庫的設計和實現,中間和mysql的恩恩怨怨給廣大喜歡交流學習的網友們,提供一些借鑒的機會。首先從mysql的批量插入開始吧。
一直自認為對sql語句的數量使用,完全絕對的低估了現實問題的難度。100w的產品基礎數據插入用掉了10個小時的時間。很挫…第一批實驗數據100w插入后,讓我久久不能釋懷,這10個小時讓我很糾結。找原因吧,之前先入為主,一顆天真爛漫的心被一篇jdbc批處理survey的文章所蒙蔽,一直以為批處理的性能不會比單獨insert要更快,那就試一下吧。【本文不談java代碼的優化】
PreparedStatement pstmt = null; Connection con = null; try { con = JdbcUtil.getConnection(); con.setAutoCommit(false); pstmt = con.prepareStatement(sql, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); String[] lines = temp.split(ConstUtil.DELIM_ENTER, -1); for (int i = 0; i < lines.length; i++) { String[] pdArr = lines[i].split(ConstUtil.DELIM_ONE, -1); if (pdArr.length < 5) return; pstmt.setString(1, pdArr[0]); if (pdArr[1].length() > 13) continue; pstmt.setString(2, pdArr[1]);// isbn pstmt.setString(3, pdArr[2]); pstmt.setString(4, pdArr[3]); pstmt.setString(5, pdArr[4]); pstmt.addBatch(); } pstmt.executeBatch(); con.commit();
還是100w的實驗數據: 首先批處理Threshold=100
Time consuming: 8h
然后批處理Threshold=500
Time consuming: 6.7h
然后批處理Threshold=1000
Time consuming: 5.4h
然后批處理Threshold=2000
Time consuming: 5.3h
看來批處理還是能節省相當的時間。不過Threshold在大也沒有多少優化空間了。不過5個多小時的插入時間還是讓心情沉重。再想想別的方法,記得jdbc-mysql的實現的新版本中增加了對批處理的支持的優化,那可以試一下嘛。 jdbc driver版本 5.1.8及以上支持rewriteBatchedStatements=true參數,該參數幫主mysql打開批處理狀態,只需在jdbc url后跟一個參數rewriteBatchedStatements=true即可(jdbc:mysql:///test?rewriteBatchedStatements=true)。
下載地址: http://www.mysql.com/products/connector/
然后批處理Threshold=1000
Time consuming: 0.5h
oha,到此批處理的結果才令人滿意(600 records/s)
來自: http://www.adintellig.com/mysql-bulk-insert-optimization/