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(1)

                .Take(1)

                .ToList();


            var example2 = blogs

                .Skip(10)

                .Take(10)

                .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 = 1;
var example1 = blogs.Skip(count).Take(count).ToList();count = 10;
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 > 1).ToList();
var skipTakeWithInt2 = blogs.OrderBy(b => b.Id).Where(d => d.Name.Length > 10).ToList();

看出什么没有,对于上述两条查询则是对应进行了两次SQL查询,这下意识到了其中玄机了吧,下面我们将上述再改造一下:

            var ef = new EFCoreContext();      
var blogs = ef.Blogs;
var length = 1;
var skipTakeWithVariable1 = blogs.OrderBy(b => b.Id).Where(d => d.Name.Length > length).ToList();length = 10;
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 = 1;
var example1 = new ExampleClass1() { Length = length };  
         
var skipTakeWithVariable1 = blogs.OrderBy(b => b.Id).Where(d => d.Name.Length > example1.Length).ToList();length = 10;
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原理解析,敬请期待。

原文地址:http://www.cnblogs.com/CreateMyself/p/6665423.html


.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/326163.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微服务为什么离不开spring cloud?

转载自 微服务为什么离不开spring cloud? 现如今微服务架构十分流行&#xff0c;而采用微服务构建系统也会带来更清晰的业务划分和可扩展性。同时&#xff0c;支持微服务的技术栈也是多种多样的&#xff0c;本系列文章主要介绍这些技术中的翘楚——Spring Cloud。这是序篇&a…

html画等边三角形,前台面试:使用CSS画一个等边三角形

CSS是前台面试必考的内容&#xff0c;有时候会面试官会出题让你画少量基本图形。由于画图的过程中可以考察很多的CSS知识点。今天我们就和大家详情一个比较难得等边三角形。思路是利使用三个div的边框来拼成一个三角形&#xff0c;只要要调整好左右两个div边框的旋转角度&#…

CSS3美化网页元素

一、CSS的作用&#xff1a; 1.有效的传递页面信息。 2.使用CSS美化过的页面&#xff0c;使得页面更加漂亮&#xff0c;吸引用户。 3.可以很好的突出页面的主题内容。 4.具有良好的用户体验。 二、span标签的作用&#xff1a; 自己本身在网页中不起作用&#xff0c;但是可以让某…

2017蓝桥杯省赛---java---A---1(迷宫)

题目描述 X星球的一处迷宫游乐场建在某个小山坡上。 它是由10x10相互连通的小房间组成的。房间的地板上写着一个很大的字母。 我们假设玩家是面朝上坡的方向站立&#xff0c;则&#xff1a; L表示走到左边的房间&#xff0c; R表示走到右边的房间&#xff0c; U表示走到上坡方…

Android之ZXing扫描二维码以及生成二维码

Android之ZXing扫描二维码以及生成二维码 ZXIng项目地址&#xff1a;ZXing地址 项目结构 扫描二维码&#xff1a;使用 CaptureActivity类 项目代码&#xff1a; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; impo…

[认证授权] 2.OAuth2授权(续) amp;amp; JSON Web Token

0. RFC6749还有哪些可以完善的&#xff1f; 0.1. 撤销Token 在上篇[认证授权] 1.OAuth2授权 中介绍到了OAuth2可以帮我们解决第三方Client访问受保护资源的问题&#xff0c;但是只提供了如何获得access_token&#xff0c;并未说明怎么来撤销一个access_token。关于这部分OAut…

Nginx动静分离实现负载均衡

转载自 Nginx动静分离实现负载均衡 前期准备 使用Debian环境。安装Nginx(默认安装)&#xff0c;一个web项目&#xff0c;安装tomcat(默认安装)等。 Nginx.conf配置 1 # 定义Nginx运行的用户 和 用户组 如果对应服务器暴露在外面的话建议使用权限较小的用户 防止被入侵2 # …

浮动

一、标准文档流&#xff1a; 1.指元素根据块级元素或行内元素的特性按从上到下&#xff0c;从左到右的方式自然排列&#xff0c;默认的排序方式。 二、块级元素&#xff1a; div,p,列表&#xff1a;宽度默认为浏览器的宽度&#xff0c;可以单独设置宽和高 三、行内元素&#xf…

html5动画是什么,10个HTML5动画 让你忘掉Flash是啥(组图)

你最近可能已经听到了很多关于Flash是面临垂死挣扎的技术以及它将如何很快被HTML5的取代。就个人而言&#xff0c;我认为HTML5会慢慢取代一些Flash的东西&#xff0c;但Flash会永远有它的一席之地&#xff0c;特别是开发复杂的游戏和丰富的互联网应用。如果你还没有看到HTML5动…

Android之Bitmap高效缓存以及android缓存策略

Android之Bitmap高效缓存 一、Bitmap高效加载 1、bitmap的基本概念 位图&#xff1a;获取像素值进行加载。 Bitmap是Android系统中图像处理中的最重要的一个类。 通过Bitmap我们也看获取图片的信息 获取到信息后&#xff0c;我们可以对其进行缩放、裁剪等操作 2、Bitmap的…

2016蓝桥杯省赛---java---A---6(寒假作业)

题目描述 现在小学的数学题目也不是那么好玩的。 看看这个寒假作业&#xff1a;□ □ □ □ - □ □ □ □ □ □ □ □(如果显示不出来&#xff0c;可以参见【图1.jpg】)每个方块代表1~13中的某一个数字&#xff0c;但不能重复。 比如&#xff1a; 6 7 13 9 - 8 1 …

微服务网关Ocelot

微服务网关是微服务架构中的核心组件,它是客户端请求的门户,它是调用具体服务端的桥梁.下面我们将使用开源项目Ocelot&#xff08;https://github.com/geffzhang/Ocelot&#xff09;搭建一款轻量级服务网关,不过在此之前我们将对微服务网关做个详细介绍,以便大家更加清晰的了解…

定位网页元素

定位网页元素一、position属性&#xff1a; 1.static&#xff1a;默认值&#xff0c;网页没有定位 2.relative:相对定位 &#xff08;1&#xff09;设置相对定位的元素&#xff0c;盒子会相对于他原来的位置进行偏移&#xff0c;达到新位置。 &#xff08;2&#xff09;设置相对…

分表分库时机选择及策略

转载自 分表分库时机选择及策略 一. 分表 应用场景&#xff1a; 对于大型的互联网应用来说&#xff0c;数据库单表的记录行数可能达到千万级甚至是亿级&#xff0c;并且数据库面临着极高的并发访问。采用Master-Slave复制模式的MySQL架构&#xff0c;只能够对数据库的读进…

html session 登录页面跳转页面跳转页面,session失效后跳转到登陆页面

一、编写Filter拦截器类package com.pv.utils;import java.io.IOException;import java.io.PrintWriter;import javax.servlet.*;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;public …

pagerAdapter 与FragmentPagerAdapter的区别

转自&#xff1a;http://blog.csdn.net/dreamzml/article/details/9951577 ViewPager ViewPager 如其名所述&#xff0c;是负责翻页的一个 View。准确说是一个 ViewGroup&#xff0c;包含多个 View 页&#xff0c;在手指横向滑动屏幕时&#xff0c;其负责对 View 进行切换。为了…

2015蓝桥杯省赛---java---A---2(星系炸弹)

题目描述 思路分析 方案一 方案二 package TEST;import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date;class Main{public static void main(String[] args) {SimpleDateFormat dateFormat new SimpleDateFormat("yyyy-MM-dd");…

NuGet社区使用体验调查

Nuget 是我们使用.NET Core的一项基础设施&#xff0c;针对国内访问NuGet服务器速度不稳定的问题我们希望通过收集一些来自用户的反馈来改善社区使用NuGet的体验。恳请您花2-3分钟时间完成以下的问题&#xff0c;我们会非常重视您的反馈。当我们收集完成所有的问卷&#xff0c;…

在护卫神上部署javaWeb项目,已经测试通过

以前一直在护卫神上部署PHP项目&#xff0c;今天忽然来了需求是部署javaWeb项目&#xff0c;刚开始一脸蒙蔽&#xff0c;后来发现也不是很难。那么接下来我们看看怎么在护卫神上部署java项目&#xff1a; 第一步&#xff1a;打开护卫神&#xff0c;在护卫神中添加一个网站&…

为什么选择微服务架构?如何取舍?

转载自 为什么选择微服务架构&#xff1f;如何取舍&#xff1f; 微服务是什么 微服务是一种架构风格&#xff0c;一个大型复杂软件应用由一个或多个微服务组成。系统中的各个微服务可被独立部署&#xff0c;各个微服务之间是松耦合的。每个微服务仅关注于完成…