Mybatis+mysql批量插入性能分析測試
閱讀目錄
- 前言
- 環境說明
- 方法說明
- 結果說明
- 測試說明
- 結論
前言
今天在網上看到一篇文章(後文中的文章指的就是它)
https://www.jianshu.com/p/cce617be9f9e
發現了一種有關於mybatis批量插入的新方法,而且看了文章發現我原來的方法好像有點問題,但是由於文章中使用的環境是sqlserver而我經常使用的是mysql所以還是需要親自來試試。
環境說明
項目使用springboot mybatis
資料庫mysql5.7
使用本地mysql所以網路可以忽略不計
插入對象完全相同,只有id自增
表結構如下:
CREATE TABLE order_test_tab (
id int(11) NOT NULL AUTO_INCREMENT COMMENT "id",
order_id varchar(20) NOT NULL COMMENT "訂單號",
order_name varchar(100) NOT NULL COMMENT "訂單名稱",
order_status int(1) NOT NULL COMMENT "訂單狀態",
order_content varchar(255) NOT NULL COMMENT "訂單說明",
add_time datetime NOT NULL COMMENT "訂單時間",
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT="測試訂單表";
方法說明
我使用了和文章中提到的一樣,三種方法進行測試
方法一:
使用for循環調用單條插入
?
?
方法二:
在sql中使用foreach進行批量insert
?
方法三:
使用mybatis的批量插入
?
結果說明
插入條數10050010005000100000使用for循環插入139ms545ms839ms2629ms31157ms使用sql foreach插入55ms119ms123ms329ms報錯使用批量執行插入48ms111ms239ms1081ms19235ms
其中報錯是因為sql長度過長超過了max_allowed_packet導致的,報錯信息如下:
Error updating database. Cause: com.mysql.cj.jdbc.exceptions.PacketTooBigException: Packet for query is too large (22,700,108 > 4,194,304). You can change this value on the server by setting the "max_allowed_packet" variable.
從結果我們顯然可以看出,使用第二種方式(使用sql foreach插入)效率最高,明顯與文章中差距很大,所以mysql和sqlserver還是有很大區別的,估計mysql針對批量插入的語句有過優化
測試說明
1.測試具體插入之前,首先執行刪除表中所有數據操作,一個是保證環境完全一致,一個是為了減少第一次連接資料庫所帶來的性能消耗。
2.執行時間的計算就是在執行sql的前後,創建對象的時間不計算在這之內
3.在使用本地mysql測試完成之後,使用外網伺服器的mysql進行測試,測試結果基本一致,時間都略有延長
4.測試代碼在:https://github.com/LinkinStars/springBootTemplate/tree/test-batch-insert
其中包含order字樣的為測試相關代碼,別的是無關代碼,入口在test包下的OrderTest.java
結論
批量插入時還是使用sql foreach插入來的效率最高,因為它是整一條sql在執行所以當插入條數很多的時候會出現異常,所以使用這種方式時一定要主動限制插入的最大條數,不然容易出現異常,因為max_allowed_packet即使再大也會有不夠用的時候。
同時我們也應該竟可能去避免使用for循環插入數據,因為性能真的很差。
作者:LinkinStar
原文:https://www.cnblogs.com/linkstar/p/10230000.html
※徹底理解 Node.js 中的回調(Callback)函數
※vue項目性能優化(路由懶載入、gzip加速、cdn加速)
TAG:程序員小新人學習 |