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