第八节: EF的性能篇(一) 之 EF自有方法的性能测试
一. 開發(fā)中常見的性能問題
? 我們在日常開發(fā)過程中,由于一些不好的習慣,經(jīng)常會導致所寫的代碼性能低下,卻毫無發(fā)覺,下面就總結一下常見的一些性能問題。
1. 真假分頁
① 假分頁:?db.xxx.toList().Skip(2).take(4) 。
?② 真分頁:db.xxx.Skip(2).take(3).toList() 。
2. 合理的使用EF的數(shù)據(jù)加載方式
? EF的加載方式有:立即加載、延遲加載、顯示加載。
詳見:
?、?#xff1a;?第五節(jié): EF高級屬性(一) 之 本地緩存、立即加載、延遲加載(不含導航屬性)
②:?第六節(jié): EF高級屬性(二)?之延遲加載、立即加載、顯示加載(含導航屬性)。
?
3. NoTracking的使用
? EF查詢出來的實體,默認是跟蹤狀態(tài)的,如果查詢出來的實體不需要修改或者刪除,查詢的時候可以刪除狀態(tài)跟蹤,變?yōu)镈etached狀態(tài),來提高性能。
? 關于EF狀態(tài)的跟蹤,詳見后面章節(jié),敬請期待!!
1 using (DbContext context = new MyDbContext()) 2 { 3 var people = context.Student.Where(p => p.Id > 2).AsNoTracking().ToList(); 4 }4. 合理的使用SQL事務
將與事務無關的一些SQL語句放到事務外,如果一個事務中的SQL語句過長,很容易出現(xiàn)死鎖問題,壓力測試時,出現(xiàn)資源被鎖的錯誤。
?
二. 關于EF數(shù)據(jù)操作的性能問題
? EF自誕生以來,大批量的操作增加、刪除、修改操作數(shù)據(jù)效率一直很低,1000條數(shù)據(jù)以內,效率尚且可以接受(10s內),但隨著數(shù)據(jù)量逐漸增大,很容易在執(zhí)行的過程中就宕機了,相當尷尬。在本章節(jié),我們一起來測試一下,EF在不進行任何優(yōu)化的情況下,幾種寫法的效率問題。
我們這里的測試是以增加數(shù)據(jù)為例,先把測試的三種寫法的結論貼上。
1.?每添加1條數(shù)據(jù),savechange一下(小白常犯的錯誤,堅決抵制這種做法!!)
1 private static void NewMethod1(DbContext db)2 {3 Console.WriteLine("-------------1. 每添加1條數(shù)據(jù),savechange一下(小白常犯的錯誤,堅決抵制這種做法!!)-------------------");4 Stopwatch watch = Stopwatch.StartNew();5 for (int i = 0; i < 1000; i++)6 {7 TestOne t = new TestOne();8 t.id = Guid.NewGuid().ToString("N");9 t.t1 = "t1+" + i; 10 t.t1 = "t2+" + i; 11 db.Set<TestOne>().Add(t); 12 db.SaveChanges(); 13 } 14 watch.Stop(); 15 Console.WriteLine("1000條數(shù)據(jù)耗時:{0}", watch.ElapsedMilliseconds); 16 }2.?先將所有數(shù)據(jù)添加到內存里,最后再savechange
1 private static void NewMethod2(DbContext db, int count)2 {3 Console.WriteLine("-------------2. 先將所有數(shù)據(jù)添加到內存里,最后再savechange-------------------");4 Stopwatch watch = Stopwatch.StartNew();5 for (int i = 0; i < count; i++)6 {7 TestOne t = new TestOne();8 t.id = Guid.NewGuid().ToString("N");9 t.t1 = "t1+" + i; 10 t.t1 = "t2+" + i; 11 db.Set<TestOne>().Add(t); 12 } 13 db.SaveChanges(); 14 watch.Stop(); 15 Console.WriteLine("{0}條數(shù)據(jù)耗時:{1}", count, watch.ElapsedMilliseconds); 16 }3.?使用addRange方法,先將數(shù)據(jù)加到list集合中,然后一次性通過addRange加到內存里
1 private static void NewMethod3(DbContext db, int count)2 {3 Console.WriteLine("-------------3. 使用addRange方法,先將數(shù)據(jù)加到list集合中,然后一次性通過addRange加到內存里-------------------");4 Stopwatch watch = Stopwatch.StartNew();5 List<TestOne> tList = new List<TestOne>();6 for (int i = 0; i < count; i++)7 {8 TestOne t = new TestOne();9 t.id = Guid.NewGuid().ToString("N"); 10 t.t1 = "t1+" + i; 11 t.t1 = "t2+" + i; 12 tList.Add(t); 13 } 14 db.Set<TestOne>().AddRange(tList); 15 db.SaveChanges(); 16 watch.Stop(); 17 Console.WriteLine("{0}條數(shù)據(jù)耗時:{1}", count, watch.ElapsedMilliseconds); 18 }?
? 總結:EF自有的方法,三個階段如上,數(shù)據(jù)超過1000條,性能直線下降,那么怎么來解決EF處理大數(shù)據(jù)量的性能問題呢?敬請期待下一個章節(jié):???第九節(jié): EF的性能篇(二) 之 Z.EntityFramework.Extensions程序集解決EF的性能問題
總結
以上是生活随笔為你收集整理的第八节: EF的性能篇(一) 之 EF自有方法的性能测试的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 秒变“建模师”!iOS 16引入新功能:
- 下一篇: AMD首颗4nm Zen 4锐龙APU处