日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

第二十三节: EF性能篇(三)之基于开源组件 Z.EntityFrameWork.Plus.EF6解决EF性能问题

發布時間:2023/12/10 编程问答 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 第二十三节: EF性能篇(三)之基于开源组件 Z.EntityFrameWork.Plus.EF6解决EF性能问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一. 開篇說明

  EF的性能問題一直以來經常被人所吐槽,究其原因在于“復雜的操作在生成SQL階段耗時長,且執行效率不高”,但并不是沒有辦法解決,從EF本身舉幾個簡單的優化例子:

  ①:如果僅是查詢數據,并不對數據進行增、刪、改操作,查詢數據的時候可以取消狀態追蹤。

db.TestInfor.AsNoTracking().FirstOrDefault();

  ②:用什么查什么,比如一張表有100多個字段,本次業務只需要5個字段,一定是select這5個字段,然后toList,而不是全部查詢,再toList()

  ③:利用EF調用原生SQL語句或者EF調用存儲過程執行。 (目前為止,沒有發現該方式存在什么問題,而且性能也很快,廣大博友如果認為這種方式存在什么問題,可以留言給我普及掃盲一下

  以上的幾種方式,或許在一定程度上能解決一些問題,但面對大數據量的增、刪、改,還是心有力而力不足。

1. 前面的章節

  前面的章節提到了Z.EntityFramework.Extensions?插件解決EF性能問題,該插件確實很nb,性能很高,而且功能很全,但是呵呵,天上沒有掉餡餅的好事,該插件是收費的,如果你公司不差錢,或者你是土豪,那么強烈推薦使用該插件,性能確實不錯,并且你可以直接右上角 x,不需要看該篇文章了^_^。

  但往往現實是殘酷,窮人居多,這個時候就需要找免費的解決方案了,前面章節提到了?SqlBulkCopy?類(與EF沒有半毛錢關系),它可以實現增加操作,不得不說,它在處理大數據量的增加的時候,確實很出色!!!。

  那么刪除和更新怎么辦呢?

  答案是:可以借助?Z.EntityFrameWork.Plus.EF6?才解決。

2. 進入主題

  Z.EntityFrameWork.Plus.EF6? 和?Z.EntityFramework.Extensions?是同一公司的產物,該插件支持的功能很多,比如 刪除、更新、緩存機制、過濾器等等,但唯獨沒有新增操作(都懂得,什么功能都有的話,他的兄弟?Z.EntityFramework.Extensions?怎么辦?)。 

  本章節僅介紹刪除和更新兩個最常用的功能。 

該插件的幾點說明:?

  ①:僅支持EF5、EF6、EF Core,注意不同的版本對應該插件的后綴不同,該章節使用的是EF 6.2,所以對應?Z.EntityFrameWork.Plus.EF6?

  ②:官方號稱:Improve EF Performance by 2000%

  ③:可以通過Nuget進行安裝

  ④:文檔地址? ? :? http://entityframework-plus.net/batch-delete

    GitHub地址:?https://github.com/zzzprojects/EntityFramework-Plus

?3. 數據庫準備

  

?

二.?刪除相關

1. Delete() 同步刪除方法

2. DeleteAsync() 異步刪除方法 <根據實際業務場景選擇使用>

3. BatchSize:批次大小

  Delete和DeleteAsync兩個刪除方法都可以設置該參數的值:x => x.BatchSize,該參數表示一次執行的條數,默認值為4000,比如你要刪除4w條數據,默認值的話,就要刪除10次,

適當的提高該值,會增加刪除效率,但并不代表無限增大。

特別注意:下面測試使用的Delete方法是默認塊級大小4000的情況下進行測試,后面把BatchSize直接改為8w,刪除8w條數據在1.6s左右

4:BatchDelayInterval:批次執行的時間間隔

  比如BatchSize=4000,BatchDelayInterval=1000,刪除4w條數據,表示的意思是刪除4000的時候等待1s,然后再刪除。

  PS:該參數不是很常用,適用于你既需要刪除很多數據,而且在批處理之間的暫停間隔繼續執行CRUD操作

5:Executing:執行刪除命令之前,去執行一段命令文本

  PS:根據實際場景選擇使用。

下面進行性能測試:(1w條、 4w條?8w條數據的刪除操作)

?(1). EF原生刪除代碼

1 /// <summary>2 /// EF普通方法測試性能3 /// </summary>4 /// <param name="db"></param>5 public static void DeleteCommon1(DbContext db)6 {7 Console.WriteLine("---------------------調用普通方法1刪除--------------------------------");8 var list=db.Set<TestTwo>.Where(u=>u.id!="1").ToList(); 9 Stopwatch watch = Stopwatch.StartNew(); 10 foreach (var item in list) 11 { 12 db.Entry(item).State = EntityState.Deleted; 13 } 14 int count = db.SaveChanges(); 15 watch.Stop(); 16 Console.WriteLine($"{count}條數據耗時:{watch.ElapsedMilliseconds}"); 17 }

?(2). EF調用SQL語句的代碼

1 /// <summary>2 /// EF調用SQL語句測試刪除3 /// </summary>4 /// <param name="db"></param>5 public static async void DeleteCommon2(DbContext db)6 {7 Stopwatch watch = Stopwatch.StartNew();8 string sql = "delete from TestTwo where id !='1' ";9 int count = 0; 10 //加上await,表示在這一步上異步方法執行完 11 var response = await db.Database.ExecuteSqlCommandAsync(sql); 12 count = response; 13 Console.WriteLine("異步方法已經開始執行,請耐心等待"); 14 watch.Stop(); 15 Console.WriteLine($"{count}條數據耗時:{watch.ElapsedMilliseconds}"); 16 }

(3). 利用該插件擴展的代碼

1 public static void DeletePlus(DbContext db)2 {3 Console.WriteLine("---------------------調用擴展方法刪除--------------------------------");4 Stopwatch watch = Stopwatch.StartNew();5 int count = db.Set<TestTwo>().Where(u => u.id != "1").Delete();6 //設置塊級大小(默認4000)7 //int count = db.Set<TestTwo>().Where(u => u.id != "1").Delete(u => u.BatchSize = 80000);8 watch.Stop();9 Console.WriteLine($"{count}條數據耗時:{watch.ElapsedMilliseconds}"); 10 }

最終的測試結論(下面的時間是取三次結果的平均值):

          1w條數據     4w條數據   ? ?  8w條數據

EF原生刪除   ? ?   ?76s?      累哭了    ? ?  累哭了

EF調SQL語句  ? ?   1.152s? ? ?   ? 1.232s       ? ?1.558s

Z.Plus(默認塊)? ?   1.307s?    1.982s?      ?2.675s

  最終結論:?Z.EntityFrameWork.Plus.EF6的刪除比EF原生要快的多! 但EF直接調用SQL語句貌似更快哈。

?

三. 更新相關

?  有了上面刪除的基礎,這里的更新操作就容易的多,更新的性能提升與刪除類似,這里不再單獨測試了,下面簡單粗暴,直接介紹用法。

1. Update() 同步更新方法

2. UpdateAsync() 異步更新方法

3. Executing:上述兩個方法的一個參數,表示執行更新命令之前,去執行一段命令文本(根據實際情況選擇使用)

?直接上代碼:

1 public static void UpdatePlus(DbContext db)2 {3 Console.WriteLine("---------------------調用擴展方法更新--------------------------------");4 Stopwatch watch = Stopwatch.StartNew();5 int count = db.Set<TestTwo>().Where(u => u.id != "1").Update(x => new TestTwo()6 {7 t21 = "0",8 t22 = "1"9 }); 10 watch.Stop(); 11 Console.WriteLine($"{count}條數據耗時:{watch.ElapsedMilliseconds}"); 12 }

?

  綜述:該插件的使用非常簡單,在使用上,可以說沒有任何難度可言,很多情況下,并不是你不會解決,而是你缺少一雙善于發現的眼鏡。

  免費的大數據解決方案: SqlBulkCopy +?Z.EntityFrameWork.Plus + EF調用SQL語句/存儲過程? ? ?或許是一個不錯的選擇。

?

總結

以上是生活随笔為你收集整理的第二十三节: EF性能篇(三)之基于开源组件 Z.EntityFrameWork.Plus.EF6解决EF性能问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。