.背景 mysql
用戶修改佈局時,須要批量更新mysql的xxxx_layout_xxxx表。批量操做的數據量是2-30條/次。批量操做是此次項目在技術上比 較關鍵的一個點,以前批量操做作過性能上的測試,mysql端問題不大,7000+tps,Java端的效率有些差,有優化空間。 sql
對批量的性能進行了測試,優化。過程以下。 數據庫
經測試,批量更新30條記錄的時間是35ms。因爲數據在mysql服務端中會有內存緩存,批量更新30條的時間用了35ms,感受有些長,試圖找出緣由。 緩存
使用截包工具(這裏用的ethereal),抓取mysql的數據包,下面是一次批量更新的數據包: 併發
能夠看出,批量更新時,每條update語句都去mysql請求了一次。並無打包發給mysql。這種批量的效率確定不會高。一樣方法試了下oracle數據庫,oracle驅動作的就很好,一次批量是打包在同一個請求中,是真正的批量提交,效率天然比mysql高。 oracle
找了些資料,發現mysql默認狀況確實是不支持batch。爲了解決上面的問題,須要給JDBC鏈接加上參數rewriteBatchedStatements=true,而且jdbc driver須要升級到5.1.8以上才支持這個參數。 工具
增長參數rewriteBatchedStatements=true,driver版本升到5.1.17後,再次測試,批量更新30條的時間從35ms降到了11ms。截包後,能夠看出底層的機制,已經變成批量提交: 佈局
查看包的內容能夠發現,這條請求裏,封裝了30條update語句 性能
橫座標: 一次批量更新的條數。縱座標:更新100次所用時間(ms) 測試
可見,當批量條數增長時,rewriteBatchedStatements=true的性能有很大優點。即便數量少時,也仍是有必定優點。
結論:
使用rewriteBatchedStatements=true參數,對批量操做,性能有較大提升,從官方解釋上看,對普通操做沒有影響。 從網上資料和本身的測試上看,暫時沒有發現rewriteBatchedStatements=true參數Driver版本5.1.17的問題。 所以,本項目中計劃採起下面優化措施:
附:
測試環境:
mysql JDBC 3.0.4/3.1.17。
客戶端: 普通PC機。
鏈接池數: 1-10。
10線程併發,批量更新30條記錄(索引有效),循環更新100次。
批量更新主要代碼:
mmpSqlMapClient.startTransaction(); // 使用事務
mmpSqlMapClient.startBatch(); // 批量提交
for (ChannelLayoutDO channelLayout: userChannelLayoutList) { mmpSqlMapClient.update(「UserChannelLayoutDAO.updateSort」, channelLayout);
}
mmpSqlMapClient.executeBatch();
mmpSqlMapClient.commitTransaction();