EF?Core通過顯式編譯提高查詢性能
今天,我將向您展示這些EF Core中一個(gè)很酷的功能,通過使用顯式編譯的查詢,提高查詢性能。
不過在介紹具體內(nèi)容之前,需要說(shuō)明一點(diǎn),EF Core已經(jīng)對(duì)表達(dá)式的編譯使用了緩存;當(dāng)您的代碼需要重用以前執(zhí)行的查詢時(shí),EF Core將使用哈希查找并從緩存中返回已編譯的查詢。
不過,您可能希望直接對(duì)查詢進(jìn)行編譯,跳過哈希的計(jì)算和緩存查找。我們可以通過在EF
靜態(tài)類中下面兩個(gè)方法來(lái)實(shí)現(xiàn):
- EF.CompileQuery()
- EF.CompileAsyncQuery()
這些方法允許您定義一個(gè)已編譯的查詢,然后通過調(diào)用一個(gè)委托調(diào)用它。
為了避免因?yàn)閿?shù)據(jù)庫(kù)查詢產(chǎn)生測(cè)試結(jié)果的差異,我們這里使用內(nèi)存數(shù)據(jù)庫(kù),它開銷更小,同時(shí)也可以避免數(shù)據(jù)庫(kù)優(yōu)化執(zhí)行計(jì)劃以及緩存所帶來(lái)的問題。
實(shí)體定義以前數(shù)據(jù)庫(kù)DbContext
定義實(shí)體
在這我們定義一個(gè)Category
實(shí)體類型,非常簡(jiǎn)單,只有兩個(gè)屬性。
public class Category { public Guid Id { get; set; } public string Name { get; set; } }
數(shù)據(jù)庫(kù)DbContext
在FillCategories
方法中,將內(nèi)存數(shù)據(jù)庫(kù)中增加三條記錄。
public class TestDbContext : DbContext { public TestDbContext(DbContextOptions<TestDbContext> options) : base(options) { } public DbSet<Category> Categories { get; set; } public void FillCategories() { var foodCategory = new Category { Id = Guid.NewGuid(), Name = "Food" }; Categories.AddRange(foodCategory, new Category { Id = Guid.NewGuid(), Name = "Drinks" }, new Category { Id = Guid.NewGuid(), Name = "Clothing" }, new Category { Id = Guid.NewGuid(), Name = "Electronis" }); SaveChanges(true); } }
測(cè)試代碼
public class CompileQueryTest { private Func<TestDbContext, Guid, Category> _getCategory = EF.CompileQuery((TestDbContext context, Guid id) => context.Categories.FirstOrDefault(c => c.Id == id)); private readonly TestDbContext _dbContext; public CompileQueryTest() { var options = new DbContextOptionsBuilder<TestDbContext>().UseInMemoryDatabase(Guid.NewGuid().ToString()).Options; var context = new TestDbContext(options); context.FillCategories(); _dbContext = context; } private readonly Guid _queryId = Guid.NewGuid(); [Benchmark] public void CompiledQuery() { _ = _getCategory(_dbContext, _queryId); } [Benchmark] public void UnCompiledQuery() { _ = _dbContext.Categories.FirstOrDefault(c => c.Id == _queryId); } }
為了更加接近測(cè)試結(jié)果,我們?cè)跇?gòu)造函數(shù)中創(chuàng)建TestDbContext
對(duì)象以及填充數(shù)據(jù)庫(kù)。
測(cè)試結(jié)果
我們使用Benchmark.Net進(jìn)行基準(zhǔn)測(cè)試,測(cè)試結(jié)果如下:
Method | Mean | Error | StdDev |
---|---|---|---|
CompiledQuery | 10.59 us | 0.0580 us | 0.0543 us |
UnCompiledQuery | 79.55 us | 0.7860 us | 0.7353 us |
經(jīng)過編譯的查詢比未編譯過的查詢存在接近8倍的差距。如果您對(duì)這個(gè)功能感興趣,不防自己測(cè)試一下。
到此這篇關(guān)于EF Core通過顯式編譯提高查詢性能的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
asp.net 因?yàn)閿?shù)據(jù)庫(kù)正在使用的解決方法
因?yàn)閿?shù)據(jù)庫(kù)正在使用,所以未能獲得對(duì)數(shù)據(jù)庫(kù)的排它訪問權(quán)?2009-02-02asp.Net 中獲取一周第一天,一月第一天等實(shí)現(xiàn)代碼
.Net中獲取一周第一天、最后一天,一月第一天、最后一天2009-12-12asp.net 站點(diǎn)URLRewrite使用小記
asp.net的底層運(yùn)作已經(jīng)也亂談過一番, 今天記一下URLRewrite的方法。2009-11-11IIS處理Asp.net請(qǐng)求和Asp.net頁(yè)面生命周期說(shuō)明
當(dāng)一個(gè)客戶端頁(yè)面訪問IIS試圖獲取一些信息的時(shí)候,發(fā)生了什么事情?一個(gè)請(qǐng)求在通過了HTTP管道后又發(fā)生了什么?本文主要是描述這兩個(gè)過程,即IIS處理asp.net請(qǐng)求和asp.net的頁(yè)面生命周期。歡迎大家積極拍磚,共同學(xué)習(xí),共同進(jìn)步。2011-05-05ASP.NET中基于soaphead的webservice安全機(jī)制
常會(huì)用到WebService來(lái)通訊,但WebService發(fā)布后為了能調(diào)用,一般都通過發(fā)布到IIS后調(diào)用 的。在IIS里可以通過匿名訪問,但這樣大家都可能訪問,不安全,下面提供一種基于soaphead的安全機(jī)制。2016-05-05ASP.NET Core Controller與IOC結(jié)合問題整理
在本篇文章里小編給大家整理了一篇關(guān)于ASP.NET Core Controller與IOC結(jié)合問題整理內(nèi)容,有需要的朋友們可以學(xué)習(xí)下。2021-01-01ASP.NET Core 2.2中的Endpoint路由詳解
這篇文章主要介紹了ASP.NET Core 2.2中的Endpoint路由詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧2019-03-03.NET讀寫Excel工具Spire.Xls使用 重量級(jí)的Excel圖表功能(5)
這篇文章主要為大家詳細(xì)介紹了.NET讀寫Excel工具Spire.Xls使用,重量級(jí)的Excel圖表功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11