網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
今天,我將向您展示這些EF Core中一個(gè)很酷的功能,通過(guò)使用顯式編譯的查詢,提高查詢性能。
不過(guò)在介紹具體內(nèi)容之前,需要說(shuō)明一點(diǎn),EF Core已經(jīng)對(duì)表達(dá)式的編譯使用了緩存;當(dāng)您的代碼需要重用以前執(zhí)行的查詢時(shí),EF Core將使用哈希查找并從緩存中返回已編譯的查詢。
不過(guò),您可能希望直接對(duì)查詢進(jìn)行編譯,跳過(guò)哈希的計(jì)算和緩存查找。我們可以通過(guò)在EF
靜態(tài)類(lèi)中下面兩個(gè)方法來(lái)實(shí)現(xiàn):
- EF.CompileQuery()
- EF.CompileAsyncQuery()
這些方法允許您定義一個(gè)已編譯的查詢,然后通過(guò)調(diào)用一個(gè)委托調(diào)用它。
為了避免因?yàn)閿?shù)據(jù)庫(kù)查詢產(chǎn)生測(cè)試結(jié)果的差異,我們這里使用內(nèi)存數(shù)據(jù)庫(kù),它開(kāi)銷(xiāo)更小,同時(shí)也可以避免數(shù)據(jù)庫(kù)優(yōu)化執(zhí)行計(jì)劃以及緩存所帶來(lái)的問(wèn)題。
實(shí)體定義以前數(shù)據(jù)庫(kù)DbContext
定義實(shí)體
在這我們定義一個(gè)Category
實(shí)體類(lèi)型,非常簡(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(DbContextOptionsoptions) : base(options) { } public DbSet 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_getCategory = EF.CompileQuery((TestDbContext context, Guid id) => context.Categories.FirstOrDefault(c => c.Id == id)); private readonly TestDbContext _dbContext; public CompileQueryTest() { var options = new DbContextOptionsBuilder ().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)過(guò)編譯的查詢比未編譯過(guò)的查詢存在接近8倍的差距。如果您對(duì)這個(gè)功能感興趣,不防自己測(cè)試一下。
原文鏈接:https://www.cnblogs.com/tdfblog/p/ef-core-compilequery.html
相關(guān)推薦
- 2022-11-28 Android線程間通信?Handler使用詳解_Android
- 2023-03-03 react?native圖片解析流程詳解_React
- 2024-01-28 ThreadLocal,提供線程局部變量
- 2023-01-12 Android?RecyclerChart其它圖表繪制示例詳解_Android
- 2022-07-11 Jenkins修改端口號(hào), jenkins容器修改默認(rèn)端口號(hào)
- 2022-06-25 教你在VS2022?MFC程序中調(diào)用CUDA代碼的方法_C 語(yǔ)言
- 2023-02-23 Go?routine使用方法講解_Golang
- 2022-12-21 使用redis如何生成自增序列號(hào)碼_Redis
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門(mén)
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支