EF Core 使用编译查询提高性能
今天,我将向您展示这些EF Core中一个很酷的功能,通过使用显式编译的查询,提高查询性能。
不过在介绍具体内容之前,需要说明一点,EF Core已经对表达式的编译使用了缓存;当您的代码需要重用以前执行的查询时,EF Core将使用哈希查找并从缓存中返回已编译的查询。
关于这一点,您可以查阅github上面的代码QueryCompiler.cs
不过,您可能希望直接对查询进行编译,跳过哈希的计算和缓存查找。我们可以通过在EF
静态类中下面两个方法来实现:
这些方法允许您定义一个已编译的查询,然后通过调用一个委托调用它。
如果您对表达式的哈希计算感兴趣,可以看一看它的实现,非常复杂,ExpressionEqualityComparer.cs。
为了避免因为数据库查询产生测试结果的差异,我们这里使用内存数据库,它开销更小,同时也可以避免数据库优化执行计划以及缓存所带来的问题。
实体定义以前数据库DbContext
定义实体
在这我们定义一个Category
实体类型,非常简单,只有两个属性。
public class Category
{
public Guid Id { get; set; }
public string Name { get; set; }
}
数据库DbContext
在FillCategories
方法中,将内存数据库中增加三条记录。
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);
}
}
测试代码
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);
}
}
为了更加接近测试结果,我们在构造函数中创建TestDbContext
对象以及填充数据库。
测试结果
我们使用Benchmark.Net进行基准测试,测试结果如下:
Method | Mean | Error | StdDev |
---|---|---|---|
CompiledQuery | 10.59 us | 0.0580 us | 0.0543 us |
UnCompiledQuery | 79.55 us | 0.7860 us | 0.7353 us |
经过编译的查询比未编译过的查询存在接近8倍的差距。如果您对这个功能感兴趣,不防自己测试一下。
EF Core 使用编译查询提高性能的更多相关文章
- 深入理解 EF Core:使用查询过滤器实现数据软删除
原文:https://bit.ly/2Cy3J5f 作者:Jon P Smith 翻译:王亮 声明:我翻译技术文章不是逐句翻译的,而是根据我自己的理解来表述的.其中可能会去除一些本人实在不知道如何组织 ...
- EF Core 的关联查询
0 前言 本文会列举出 EF Core 关联查询的方法: 在第一.二.三节中,介绍的是 EF Core 的基本能力,在实体中配置好关系,即可使用,且其使用方式,与编程思维吻合,是本文推荐的方式. 第四 ...
- EF core的原生SQL查询以及用EF core进行分页查询遇到的问题
在用.net core进行数据库访问,需要处理一些比较复杂的查询,就不得不用原生的SQL查询了,然而EF Core 和EF6 的原生sql查询存在很大的差异. 在EF6中我们用SqlQuery和Exe ...
- Dapper, Ef core, Freesql 插入大量数据性能比较(一)
需求:导入9999行数据时Dapper, Ef core, Freesql 谁的性能更优,是如何执行的,级联增加谁性能更佳. 确认方法:sql server 的 sys.dm_exec_query_s ...
- Dapper, Ef core, Freesql 插入大量数据性能比较(二)
在上一篇文章中,我们比较出单表插入9999行数据,Dapper > EfCore > Freesql.在本文中,我们来看看级联插入 构建9999行数据 List<Entity> ...
- EntityFramework Core 2.0 Explicitly Compiled Query(显式编译查询)
前言 EntityFramework Core 2.0引入了显式编译查询,在查询数据时预先编译好LINQ查询便于在请求数据时能够立即响应.显式编译查询提供了高可用场景,通过使用显式编译的查询可以提高查 ...
- Cookies 初识 Dotnetspider EF 6.x、EF Core实现dynamic动态查询和EF Core注入多个上下文实例池你知道有什么问题? EntityFramework Core 运行dotnet ef命令迁移背后本质是什么?(EF Core迁移原理)
Cookies 1.创建HttpCookies Cookie=new HttpCookies("CookieName");2.添加内容Cookie.Values.Add(&qu ...
- EF 6.x、EF Core实现dynamic动态查询和EF Core实现多个上下文实例池你了解多少?
前言 很长一段时间没有写博客了,今天补上一篇吧,偶尔发现不太愿意写博客了,太耗费时间,不过还是在坚持当中,毕竟或许写出来的东西能帮到一些童鞋吧,接下来我们直奔主题.无论是在在EF 6.x还是EF Co ...
- 讨论过后而引发对EF 6.x和EF Core查询缓存的思考
前言 最近将RabbitMQ正式封装引入到.NET Core 2.0项目当中,之前从未接触过是个高大上的东东跟着老大学习中,其中收获不少,本打算再看看RabbitMQ有时间写写,回来后和何镇汐大哥探讨 ...
随机推荐
- mysql主从备份及常见问题处理
1.mysql主从备份基本原理 mysql支持单向.异步复制,复制过程中一个服务器充当主服务器,而一个或多个其它服务器充当从服务器.mysql复制基于主服务器在二进制日志中跟踪所有对数据库的更改(更新 ...
- Execution default of goal org.springframework.boot:spring-boot-maven-plugin:1.5.6.RELEASE:repackage failed: Unable to find main class
异常 [INFO] --- spring-boot-maven-plugin:1.5.6.RELEASE:repackage (default) @ spring-boot-starter-log - ...
- (五):C++分布式实时应用框架——支撑复杂的业务通讯关系
C++分布式实时应用框架--支撑复杂的业务通讯关系 技术交流合作QQ群:436466587 欢迎讨论交流 版权声明:本文版权及所用技术归属smartguys团队所有,对于抄袭,非经同意转载等行为保留法 ...
- ed命令
- 【java设计模式】【创建模式Creational Pattern】单例模式Singleton Pattern
//饿汉式:资源利用率较低(无论是否需要都会创建),性能较高(使用前无需判断实例是否存在,可直接使用) public class EagerSingleton{ private static fina ...
- 【java】获取当前环境属性及编码乱码示例
package 字符编码; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; impo ...
- iOS中self与_的区别
同时我们发现在我们访问我们声明的变量时,会有self. 和 以"_"开头的访问方式,那么这两种方式到底有什么样的区别呢? 我们来一起看一下: @property (retain, ...
- SQL Server AlwaysOn添加监听器失败
标签:MSSQL/ 一.错误描述 1.群集服务未能使群集服务或应用程序“Alwayson22”完全联机或脱机.一个或多个资源可能处于失败状态.这可能会影响群集服务或应用程序的可用性 2.群集服务中的群 ...
- 同时只允许Count个线程访问同一块区域的实现方式
转载请注明出处. 好吧,后来才发现有Semaphore和SemaphoreSlim这两个类. 以前的答案: 最近.Net项目中用到了网页截图功能,这个截图功能是类似后台开了一个IE浏览器默默加载某个网 ...
- ABP 用swagger UI测试API报401无权限访问问题
问题描述: 当我们用swagger UI对Web API 进行测试时报401错误 我们点开GET /api/services/app/Role/GetAll,输入参数 点击Try it out!按钮, ...