原作者地址http://blog.csdn.net/zlts000/article/details/46385773

之前做專案的時候,做出來的系統的效能不太好,在框架中使用了EntityFramework,於是就在網上查資料,研究如何提高EF的效能。 
在這分享一篇部落格 批量操作提升EntityFramework的效能 
裡面提供了一個擴充套件庫Entity Framework擴充套件庫,在這裡面找到了一些比較好的方法。下面主要介紹其中的一個方法—-批量新增BulkInsert。


這些擴充套件方法在哪裡找?


在VS中新建EF之後,右鍵解決方案下的引用, 選擇管理NuGet程式包,搜尋Z.EntityFramework.Extensions並安裝。

然後在類裡面新增引用之後就可以直接點出來。


批量新增和EF本身自帶的新增效能提高了多少?


下面咱們就用例項說話: 
構造一個10W個studentinfo例項:

            '''定義要新增資料的條數'''
int customerCount = 100000; '''定義一個實體集合'''
List<studentInfo> customers = new List<studentInfo>(); '''想集合中新增資料'''
for (int i = 0; i < customerCount; i++)
{
studentInfo customer = new studentInfo()
{
name = "2" + i,
sex = "2" + i,
studentID = "2" + i,
age = "2"
};
customers.Add(customer); Console.Write(".");
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

用EF自帶的新增方法將資料新增到資料庫中,為了計算使用時間,加上StopWatch:

'''開始計時'''
Stopwatch watch = Stopwatch.StartNew(); using (EFTestEntities dbcontext = new EFTestEntities())
{
foreach (var entity in customers)
{
dbcontext.studentInfoes.Add(entity);
}
dbcontext.SaveChanges();
} '''計時結束'''
watch.Stop(); '''輸出時間'''
Console.WriteLine(string.Format("{0} customers are created, cost {1} milliseconds.", customerCount, watch.ElapsedMilliseconds));
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

好了現在執行,等待中…… 
哎~~實在是沒有耐心等待它執行完。 
怎麼辦,減少資料量,先新增1000條:

還好,用時6157毫秒,6.157秒;

接著走,把資料量改為10000條:

執行完了,共117096毫秒,117.096秒,將近兩分鐘。實在是沒有耐心再測100000條的了,接下來直接測批量新增的方法。

將上面的新增到資料庫中的程式碼換成下面的程式碼:

dbcontext.BulkInsert(customers);

dbcontext.BulkSaveChanges();
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

直接上10W條:

執行完了,共3592毫秒,3.592秒,真快啊~~

那麼20W呢?

20W條資料執行完,才花了6346毫秒,6.346秒的時間。比上面的方法新增1000條的資料用的時間差不多,看來EF自帶的新增方法慢,是毋庸置疑的了。


為什麼擴充套件方法用的時間這麼少?


EF自帶的方法,會增加與資料庫的互動次數,一般地,EF的一個上下文在提交時會開啟一個數據連線,然後把轉換成的SQL語句一條一條的發到資料庫端,然後去提交,下面的圖片是我用SQL Server Profiler記錄的和資料庫互動的操作,這只是一小部分,試想,如果你的資料量達到萬級別(更不用說百萬,千萬資料了),那對資料庫的壓力是很大的

而擴充套件方法執行時與資料庫的互動是這樣的:

批量新增的方法是生成一條SQL語句,和資料庫只互動一次。那為什麼圖片中有多條Insert語句呢,當你使用BulkInsert時,如果資料達到4萬之前,那在SQL的解釋時,也是很有壓力的,有多情況下會超時,當然這與你的資料庫伺服器有關,但為了效能與安全,將Bulk操作變為分批提交,即將上W的資料進行分解,分用1W資料量提交一次,這樣,對資料庫的壓力就小一些。

原始碼下載:EF擴充套件方法BulkInsert(批量新增)