比較少用mysql,最近接手一個項目,遇到一個mybatis插入速度很慢的問題,但是看代碼mybatis的批量使用的是JDBC的 PrepareStatement.executeBatch,性能應該不至少太差,但是在生產環境居然只有40條/S,太慢了。搜索相關的問題,發現跟連接url的參數有問題,加上&rewriteBatchedStatements=true即可。
詳細參數說明可以參考 https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-reference-configuration-properties.html
測試JDBC時候速度很快,但是到生產環境上仍然很慢,有提升但是不是很顯著。於是把生產環境的數據扒下來測試,最后發現是mybatis每一條數據都是一個新的PreparedStatement,本來應該可以重用PrepareStatement的,但是因為每條數據都有不同的情況的NULL值(Mybatis不更新實體的NULL值字段),進而導致了Mybatis每次生成的insert sql語句幾乎都不一樣,所以每次都得生成一條新的PreparedStatement,不能真正的addBatch和executeBatch。
因此:
1、建議數據庫/實體盡量不允許NULL值字段 ,這樣子批量插入時候Mybatis能夠重用生成的PreparedStatement,實現批量提交。
2、改成INSERT INTO t_xxx VALUES(XXX, XXX), (XXX, XXX)這樣的一次提交多行的方式插入,但是此方法可能會繞過我們封裝的業務代碼,因此不太推薦此方法。