MySQL 與EF 百萬數據插入(彙總)

依次是:

方法一:循環插入(很慢)

方法二:一條sql語句n個insert

  通過合併SQL語句,同時也能減少SQL語句解析的次數,減少了數據庫連接的I/O開銷,一般會把多條數據插入放在一條SQL語句中一次執行;

  合併後日志量(MySQL的binlog和innodb的事務讓日誌)減少了,降低日誌刷盤的數據量和頻率,從而提高效率。

方法三:一個事務包裹n個insert

  因爲進行一個INSERT操作時,MySQL內部會建立一個事務,在事務內才進行真正插入處理操作。通過使用事務可以減少創建事務的消耗,所有插入都在執行後才進行提交操作。

  讀鎖是共享的,它不會阻塞其他讀鎖;寫鎖是排他的,它會阻塞其他讀鎖和寫鎖;讀讀不互斥,讀寫互斥,寫寫互斥。這裏讀寫互斥,應該說的是查詢和修改互斥,因爲實際測試發現:寫入過程中可以查詢,會看見行數在增加。

方法三:使用存儲過程(內部也用事務包裹)

方法四:使用MYSQL LOCAL_INFILE

方法五:文件導入,用LOAD方法。 

 

優化:

*主鍵和索引列數據:有順序插入。參照InnoDB使用的B+tree索引,如果每次插入記錄都在索引的最後面,索引的定位效率很高,並且對索引調整較小;如果插入的記錄在索引中間,需要B+tree進行分裂合併等處理,會消耗比較多計算資源,並且插入記錄的索引定位效率會下降,數據量較大時會有頻繁的磁盤操作。

*SQL語句是有長度限制,在進行數據合併在同一SQL中務必不能超過SQL長度限制,通過max_allowed_packet配置可以修改,默認是1M,測試時修改爲8M。

*事務需要控制大小,事務太大可能會影響執行的效率。MySQL有innodb_log_buffer_size配置項,超過這個值會把innodb的數據刷到磁盤中,這時,效率會有所下降。所以比較好的做法是,在數據達到這個這個值前進行事務提交。

有前提條件的優化:

*當只有導入,沒有查詢和修改操作時。導入開始時可關閉唯一性校驗 ,導入結束後執行,恢復唯一性校驗。(未見測試效果)

SET  UNIQUE_CHECKS=0

insert...(導入語句)

SET  UNIQUE_CHECKS=1

類似的說法: 在確保數據無重複的前提下,導入數據前刪除唯一索引,導入數據後恢復唯一索引。

*如果應用使用自動提交的方式,建議在導入前執行,關閉自動提交,導入結束後再開啓。
SET AUTOCOMMIT=0

資料:

*mysql大批量插入數據四種方法

https://blog.csdn.net/qq_36324113/article/details/90610667

*大批量數據高效插入數據庫表

https://www.cnblogs.com/myseries/p/11191134.html

*Mysql EF 數據錄入&批量數據錄入 (文件導入用load方法)

https://www.cnblogs.com/Lulus/p/12604595.html

https://www.cnblogs.com/ldj3/p/9287965.html

*SET  UNIQUE_CHECKS=0  問題的爭議

http://blog.itpub.net/20892230/viewspace-2132317/

總結:不管是innodb,還是tokudb,只有在確認需要插入的數據的唯一性是可控的,或者不違反unique性,可以關閉unique_checks來提升性能.不過,還是那句老話,只有在確保數據的安全前提下,才考慮優化和性能提升的事兒.unique_checks對於數據的校驗,還是啓了很大的作用,所以.個人建議是不要關閉該參數.爲了數據的安全.

https://www.cnblogs.com/zhouwanchun/p/13156459.html
首先,即便設置unique_checks=0,也無法往唯一索引中寫入重複值。
其次,設置unique_checks=0的作用在於,批量導入數據(例如load data)時,在確保導入數據中無重複值時,無需再次檢查其唯一性,加快導入速度。
所以,unique_checks=0並不是允許唯一約束失效,而是再批量導數據時不再逐行檢查唯一性。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章