c#資料批量插入
由於之前面試中經常被問到有關EF的資料批量插入問題,今天以Sqlserver資料庫為例,對.net中處理資料批量處理的方案進行了測試對比。
1.四種測試方案
(1)普通的EF資料批量插入:即呼叫DbSet中的Addrange方法
(2)不進行上下文跟蹤的EF資料批量插入:即關閉自呼叫的DetectChanges方法,不對每一個新增的實體進行掃描
(3)在EF中執行sql批量插入
(4)Ado.net執行sql批量插入
(5)利用sqlserver的Bcp功能作批量插入:程式碼中利用了SqlBulkCopy類
2.相關環境
(1)資料庫:sqlserver2014
(2)作業系統:win10
(3)cpu:i5-4210U
(4)記憶體:8G
3.測試
將以上5種方案,在資料量分別為100,1000,10000,100000的情況下進行測試,每種資料量級別測試3次
要插入的表如下所示:
3.1 普通的EF資料批量插入
用DbSet的AddRange方法作批量插入
3.2 不進行上下文跟蹤的EF資料批量插入
用DbSet的AddRange方法作批量插入,且上下文不對增加的實體作跟蹤,即程式碼中將context.Configuration.AutoDetectChangesEnabled設為false
3.3 在EF中執行sql批量插入
3.4 Ado.net執行sql批量插入
3.5 利用sqlserver的Bcp功能作批量插入
SqlBulkCopy類可對sqlserver資料庫作批量處理,其原理是利用了sqlserver的Bcp功能,但需要將資料先寫入到DataTable
4.測試結果
100條 | 1000條 | 10000條 | 100000條 | |
EF普通批量插入 | 331,41,51 | 1034,459,456 | 5200,5090,4921 | 55396,56479,58018 |
不進行上下文跟蹤的EF資料批量插入 | 282,44,55 | 817,1152,547 | 6022,5523,5843 | 51465,52590,52037 |
EF中執行sql批量插入 | 7,4,4 | 52,32,45 | 811,388,380 | 插不進(sqlserver單次sql插入有限制) |
Ado.net執行sql批量插入 | 75,19,49 | 204,225,218 | 2177,2678,2387 | 插不進(sqlserver單次sql插入有限制) |
SqlBulkCopy批量插入 | 26,3,3 | 8,7,10 | 120,114,97 | 820,596,368 |
*注:單位為毫秒
5.結論
(1)利用sqlBulkCopy來對sqlserver作資料批量操作要明顯好於其它四種方式,隨著資料量增加效果越明顯
(2)資料量在1萬以內,用EF來做資料插入,其效能基本是能接受的,可以從EF中執行sql批量插入這種方式中看出,所以說ef在正常的業務開發中,資料插入基本不存在效能問題
(3)很奇怪的是EF中執行sql批量插入 這種方式明顯好於原生的Ado.net執行sql批量插入這種方式,看來ef還是比較強大的