對於一些數據量較大的系統,面臨的問題除了是查詢效率低下,還有一個很重要的問題就是插入時間長。咱們就有一個業務系統,天天的數據導入須要4-5個鐘。這種費時的操做實際上是頗有風險的,假設程序出了問題,想重跑操做那是一件痛苦的事情。所以,提升大數據量系統的MySQL insert效率是頗有必要的。sql
通過對MySQL的測試,發現一些能夠提升insert效率的方法,供你們參考參考。數據庫
1. 一條SQL語句插入多條數據。
經常使用的插入語句如:網絡
INSERT INTO `insert_table` (`datetime`, `uid`, `content`, `type`) VALUES ('0', 'userid_0', 'content_0', 0); INSERT INTO `insert_table` (`datetime`, `uid`, `content`, `type`) VALUES ('1', 'userid_1', 'content_1', 1);
修改爲:性能
INSERT INTO `insert_table` (`datetime`, `uid`, `content`, `type`) VALUES ('0', 'userid_0', 'content_0', 0), ('1', 'userid_1', 'content_1', 1);
修改後的插入操做可以提升程序的插入效率。這裏第二種SQL執行效率高的主要緣由有兩個,一是減小SQL語句解析的操做, 只須要解析一次就能進行數據的插入操做,二是SQL語句較短,能夠減小網絡傳輸的IO。測試
這裏提供一些測試對比數據,分別是進行單條數據的導入與轉化成一條SQL語句進行導入,分別測試1百、1千、1萬條數據記錄。大數據
記錄數 | 單條數據插入 | 多條數據插入 |
1百 | 0.149s | 0.011s |
1千 | 1.231s | 0.047s |
1萬 | 11.678s | 0.218s |
2. 在事務中進行插入處理。
把插入修改爲:優化
START TRANSACTION; INSERT INTO `insert_table` (`datetime`, `uid`, `content`, `type`) VALUES ('0', 'userid_0', 'content_0', 0); INSERT INTO `insert_table` (`datetime`, `uid`, `content`, `type`) VALUES ('1', 'userid_1', 'content_1', 1); ... COMMIT;
使用事務能夠提升數據的插入效率,這是由於進行一個INSERT操做時,MySQL內部會創建一個事務,在事務內進行真正插入處理。經過使用事務能夠減小數據庫執行插入語句時屢次「建立事務,提交事務」的消耗,全部插入都在執行後才進行提交操做。ui
這裏也提供了測試對比,分別是不使用事務與使用事務在記錄數爲1百、1千、1萬的狀況。.net
記錄數 | 不使用事務 | 使用事務 |
1百 | 0.149s | 0.033s |
1千 | 1.231s | 0.115s |
1萬 | 11.678s | 1.050s |
性能測試:
這裏提供了同時使用上面兩種方法進行INSERT效率優化的測試。即多條數據合併爲同一個SQL,而且在事務中進行插入。日誌
記錄數 | 單條數據插入 | 合併數據+事務插入 |
1萬 | 0m15.977s | 0m0.309s |
10萬 | 1m52.204s | 0m2.271s |
100萬 | 18m31.317s | 0m23.332s |
從測試結果能夠看到,insert的效率大概有50倍的提升,這個一個很客觀的數字。
注意事項:
1. SQL語句是有長度限制,在進行數據合併在同一SQL中務必不能超過SQL長度限制,經過max_allowed_packe配置能夠修改,默認是1M。
2. 事務須要控制大小,事務太大可能會影響執行的效率。MySQL有innodb_log_buffer_size配置項,超過這個值會日誌會使用磁盤數據,這時,效率會有所降低。因此比較好的作法是,在事務大小達到配置項數據級前進行事務提交。