EntityFramework Core不得不注意的性能优化意外收获,你会用错?
前言
这两天在着实研究EF Core项目当中对于一些查询也没实际去检测,于是想着利用放假时间去实际测试下,结果本文就出来了,too young,too simple,后续博主会从底层翻译表达式树弄起,来从源头了解EF Core,通过本文你会明白不是EF Core团队没做性能优化,而是你根本就没用过而且正在倒退。
EntityFramework Core性能优化初探
简单粗暴直接上代码,给出上下文以及需要用到的测试类,如下:
public class EFCoreContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.UseSqlServer(@"Server=.;Database=EFCoreDb;Trusted_Connection=True;"); protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>(pc =>
{
pc.ToTable("Blog").HasKey(k => k.Id); pc.Property(p => p.Name).IsRequired();
pc.Property(p => p.Url).IsRequired();
pc.Property(p => p.Count).IsRequired(); pc.Property(p => p.RowVersion).IsRequired().IsRowVersion().ValueGeneratedOnAddOrUpdate();
});
}
}
你是否像如下去获取分页数据呢,我们来一起瞧瞧:
var ef = new EFCoreContext();
var blogs = ef.Blogs; var example1 = blogs
.Skip()
.Take()
.ToList(); var example2 = blogs
.Skip()
.Take()
.ToList();
我们通过如下SQL语句来查看查询计划生成的SQL语句:
SELECT
sys.syscacheobjects.cacheobjtype,
sys.dm_exec_query_stats.execution_count,
sys.syscacheobjects.SQL,
sys.dm_exec_query_plan.query_plan FROM sys.dm_exec_query_stats
INNER JOIN sys.dm_exec_cached_plans
ON sys.dm_exec_cached_plans.plan_handle = sys.dm_exec_query_stats.plan_handle
INNER JOIN sys.syscacheobjects ON sys.syscacheobjects.bucketid = sys.dm_exec_cached_plans.bucketid CROSS APPLY sys.dm_exec_query_plan(sys.dm_exec_query_stats.plan_handle)
结果如下:

我们再来看看xml文件中生成的SQL语句是怎样的。

这说明什么问题呢,上述查询计划中生成的SQL语句对于我们上述去取数据首选从第二条取一条,接下来是去取第十条后的十条,同时上述SQL语句而是声明了两个变量,换言之,上述两条语句查询最终在第一次查询后SQL查询计划进行了缓存,下次再去取数据时直接调用此SQL语句以此达到重用的目的,下面要是我们进行如下改造,结果会怎样呢?
var ef = new EFCoreContext();
var blogs = ef.Blogs; var count = ;
var example1 = blogs
.Skip(count)
.Take(count)
.ToList(); count = ;
var example2 = blogs
.Skip(count)
.Take(count)
.ToList();

结果经过上述改造利用变量的形式和直接赋值的形式是一致的,没有什么可讲的,下面我们再来讲述另外一种情况。请继续往下看。
var ef = new EFCoreContext();
var blogs = ef.Blogs; var skipTakeWithInt1 = blogs
.OrderBy(b => b.Id).Where(d => d.Name.Length > ).ToList(); var skipTakeWithInt2 = blogs
.OrderBy(b => b.Id).Where(d => d.Name.Length > ).ToList();



看出什么没有,对于上述两条查询则是对应进行了两次SQL查询,这下意识到了其中玄机了吧,下面我们将上述再改造一下:
var ef = new EFCoreContext();
var blogs = ef.Blogs; var length = ;
var skipTakeWithVariable1 = blogs
.OrderBy(b => b.Id).Where(d => d.Name.Length > length).ToList(); length = ;
var skipTakeWithVariable2 = blogs
.OrderBy(b => b.Id).Where(d => d.Name.Length > length).ToList();


我们利用变量替换值改造后结果生成的SQL语句与上述截然不同,这里同样是声明了长度的变量,你发现没该变量居然和我们声明的变量长度是一致的,有点神奇,如此这样通过变量替换值得方式来达到SQL查询计划重用的目的,说到这里,我们是不是应该回答一下为什么会有这样的情况发生呢。很多东西当你一直没用到时就觉得不会用到压根不用学,其实不然,比如这样,其本质到底是怎样的呢,其实是因为前面我已经讲过【闭包】的原因。
lambda表达式对我们声明的变量进行了捕获然后延长了其生命周期,也就是说将变量类似变成类中一个字段了,类似如下:
[CompilerGenerated]
public sealed class ExampleClass1
{
public int Length;
} [CompilerGenerated]
public sealed class ExampleClass2
{
public int Length;
}
自动编译生成两个类同时存在两个对于长度的字段。接下来当我们利用变量进行查询就演变了如下这样:
var ef = new EFCoreContext();
var blogs = ef.Blogs; var length = ;
var example1 = new ExampleClass1() { Length = length };
var skipTakeWithVariable1 = blogs
.OrderBy(b => b.Id).Where(d => d.Name.Length > example1.Length).ToList(); length = ;
var example2 = new ExampleClass2() { Length = length };
var skipTakeWithVariable2 = blogs
.OrderBy(b => b.Id).Where(d => d.Name.Length > example2.Length).ToList();
这样就很明了了为什么通过变量达到查询计划重用的目的。
总结
关于EntityFramework Core虽然目前设计的性能非常好,但是有些东西等我们去用时还得多加验证,看其背后的本质是怎样的,才能不会心生疑窦,到底该怎样用,如何用,心中要有定数才是,一点一滴的细小优化不注意最终将导致大意失荆州。接下来博主会在三个方向不定时更新博客,第一个是SQL Server性能优化系列,第二个是ASP.NET Core MVC/WebAPi,第三个则是EntityFramework Core原理解析,敬请期待。
EntityFramework Core不得不注意的性能优化意外收获,你会用错?的更多相关文章
- EntityFramework之原始查询及性能优化(六)
前言 在EF中我们可以通过Linq来操作实体类,但是有些时候我们必须通过原始sql语句或者存储过程来进行查询数据库,所以我们可以通过EF Code First来实现,但是SQL语句和存储过程无法进行映 ...
- EntityFramework之原始查询及性能优化
之前做海信项目,数据量自交大,为了提高查询效率用的 https://www.cnblogs.com/CreateMyself/p/4746258.html
- 第 10 章 MySQL Server 性能优化
前言: 本章主要通过针对MySQL Server(mysqld)相关实现机制的分析,得到一些相应的优化建议.主要涉及MySQL的安装以及相关参数设置的优化,但不包括mysqld之外的比如存储引擎相关的 ...
- MySql(十):MySQL性能调优——MySQL Server性能优化
本章主要通过针对MySQL Server( mysqld)相关实现机制的分析,得到一些相应的优化建议.主要涉及MySQL的安装以及相关参数设置的优化,但不包括mysqld之外的比如存储引擎相关的参数优 ...
- MySQL性能调优与架构设计——第10章 MySQL数据库Schema设计的性能优化
第10章 MySQL Server性能优化 前言: 本章主要通过针对MySQL Server(mysqld)相关实现机制的分析,得到一些相应的优化建议.主要涉及MySQL的安装以及相关参数设置的优化, ...
- Spark 3.x Spark Core详解 & 性能优化
Spark Core 1. 概述 Spark 是一种基于内存的快速.通用.可扩展的大数据分析计算引擎 1.1 Hadoop vs Spark 上面流程对应Hadoop的处理流程,下面对应着Spark的 ...
- EntityFramework之异步、事务及性能优化(九)
前言 本文开始前我将循序渐进先了解下实现EF中的异步,并将重点主要是放在EF中的事务以及性能优化上,希望通过此文能够帮助到你. 异步 既然是异步我们就得知道我们知道在什么情况下需要使用异步编程,当等待 ...
- Instruments性能优化-Core Animation
简书地址:http://www.jianshu.com/users/6cb2622d5eac/latest_articles 当App发展到一定的规模.性能优化就成为不可缺少的一点.可是非常多人,又对 ...
- EntityFramework Core 3多次Include导致查询性能低之解决方案
前言 上述我们简单讲解了几个小问题,这节我们再来看看如标题EF Core中多次Include导致出现性能的问题,废话少说,直接开门见山. EntityFramework Core 3多次Include ...
随机推荐
- Convex Hull 实现理论+自制Python代码
Convex Hull 概述 计算n维欧式空间散点集的凸包,有很多的方法.但是如果要实现快速运算则其难点在于:如何快速判断散点集的成员是否是在凸集的内部.如果可以简化判断的运算过程,则可以极大简化迭代 ...
- vue路由表(简单)
import Vue from 'vue'import VueRouter from 'vue-router'Vue.use(VueRouter) const first = { template: ...
- URLencode 特殊字符 转义 遇上的坑
在项目中遇到一个问题,在webveiw和原生之间进行传值的时候,出现了一些encode的小问题.看起来很简单的问题,实际上却存在不小的坑. 首先说一下目前项目的结构,在一个activity中,webv ...
- javaSE复习总结
之前匆匆忙忙学完了java,后来又接着学习ee,然而,越是想要快一点最后反而会更慢一点.因为匆忙间 我几乎什么都没学会.在后面的学习中实在非常吃力.就把javase 的视频大部分又重新看了一遍.真的收 ...
- 网络安全实验室 注入关通关writeup
URL:http://hackinglab.cn 注入关 [1] 最简单的SQL注入username = admin' or ''='password随便什么都可以直接可以登录 [2] 熟悉注入环境 ...
- 基于 Koa平台Node.js开发的KoaHub.js连接打印机的代码
最近好多小伙伴都在做微信商城的项目,那就给大家分享一个基于 Koa.js 平台的 Node.js web 开发的框架连接微信易联云打印机接口的代码,供大家学习.koahub-yilianyun 微信易 ...
- SPM HW1 A project
项目分析 --民航航班异常轨迹可视分析 最近完成的一个项目是一个可视化大作业--民航航班异常轨迹可视分析.要求利用已给的8G飞机的飞行记录数据,将飞机的飞行轨迹在浏览器中进行飞行轨迹高维可视化以及对异 ...
- SQL基本用法-行转列
/* SELECT <非透视的列>, [第一个透视的列] AS <列名称>, [第二个透视的列] AS <列名称>, ... [最后一个透视的列] AS <列 ...
- Jmeter正则提取器常用的几种方式
使用jmeter的同学都知道,jmeter提供了各种各样的提取器,如jsonpath.Beanshell.Xpath.正则等!!! 我们就针对正则提取器如何使用进行说明. 举例说明:假设取sessio ...
- Broken pipe错误终极解释
叙述 想必或多或少在Java的服务器都会遇到过这种异常,如下图 由于Java偏上层,日常开发接触系统底层的机会偏少,要搞清楚什么原因导致的这种异常,肯定是先要百度google一番. 网络 ...