#yyds干货盘点#愚公系列2023年02月.net/c#知识点-efcore性能优化之显示编译(代码片段)

author author     2023-02-24     530

关键词:

前言

性能优化,简而言之,就是在不影响系统运行正确性的前提下,使之运行地更快,完成特定功能所需的时间更短。

对于EF Core的查询优化其实也是多种多样的,性能优化是在特定的情况下的特定解决方案,下面着重介绍EF Core的显示编译查询

1.显示编译的概念

EF Core对我们查询的表达式的编译使用了缓存,当你查询代码需要重用以前执行的查询时,EF Core将使用哈希查找并从缓存中返回已编译的查询。如果能直接对查询进行编译,并跳过哈希的计算和缓存查找那么效率是否会提高呢?这就是显示编译。

说白了也就是跳过查找的过程,而且使用场景如下:

  • EF Core,还不支持编译查询返回集合类型。
  • 在数据量大的时候使用,比如查询大于一百万次时候大约回快6倍,一万次大约是2倍左右。

一、Core性能优化之显示编译

本文主要是内存数据库的方式来测试显示编译查询的性能,避免了其他因素。

显示编译的两个方法如下:

EF.CompileQuery()//同步方法
EF.CompileAsyncQuery()异步方法

这两个方法允许您定义一个已编译的查询,然后通过调用一个委托调用它。

1.安装

install-package Microsoft.EntityFrameworkCore.InMemory

2.注入

services.AddDbContext<TestDbContext>(options => 
     options.UseInMemoryDatabase(new Guid().ToString());
);//Guid是内存表名称

3.创建数据库上下文类

public class Team

    public int Id  set; get; 
    public string Name  set; get;  
    public int ageset; get;

//建立上下文,并加入Team表
public class TestDbContext : DbContext

    public TestDbContext(DbContextOptions<TestDbContext> options) : base(options)
    
    
    public DbSet<Team> Teams  get; set; 
    public void FillCategories()//插入内存数据库里
    
        var Team = new List<Team>();
        for (int i = 0; i < 100000; i++)
        
            Teams.Add(new Team  Id = i, Name = "张山", age = i + 1 );
        
        Teams.AddRange(Team);
        SaveChanges(true);
    

4.创建查询控制器类

[ApiController]
[Route("[controller]/[action]")]
public class TeamsCompileQueryController : ControllerBase

    public TestDbContext teamContext;
    public TeamsCompileQueryController(TestDbContext teamContext)
    
        this.teamContext = teamContext;
    
    [HttpGet(Name = "CompiledQuery")]
    public void CompiledQuery()
    
        Func<TestDbContext, Team> compileQuery = EF.CompileQuery((TestDbContext context) =>
            context.Teams.OrderBy(o => o.Id).FirstOrDefault())!;
        var stopWatch = new Stopwatch();
        teamContext.Database.EnsureDeleted();
        teamContext.Database.EnsureCreated();
        stopWatch.Restart();
        for (var i = 0; i < 100; i++)
        
            var blog = compileQuery(teamContext);
        
        stopWatch.Stop();
        Console.WriteLine("显示编译查询:" + stopWatch.Elapsed);
    
    [HttpGet(Name = "UnCompiledQuery")]
    public void UnCompiledQuery()
    
        Func<TestDbContext, Team> unCompileQuery = context =>
        
            return context.Teams.OrderBy(o => o.Id).FirstOrDefault()!;
        ;
        var stopWatch = new Stopwatch();
        teamContext.Database.EnsureDeleted();
        teamContext.Database.EnsureCreated();
        stopWatch.Start();
        for (var i = 0; i < 100; i++)
        
            var blog = unCompileQuery(teamContext);
        
        stopWatch.Stop();
        Console.WriteLine("常规查询:" + stopWatch.Elapsed);
    

类中有两个方法,一个是普通查询,一个是显式编译查询。

5.运行

5.1 常规查询

5.2 显示编译查询

#yyds干货盘点#愚公系列2023年02月.net/c#知识点-list转成字符串的总结(代码片段)

前言List转成字符串的总结的应用场景非常广泛,可以用于字符串拼接、数据处理和存储、显示等方面。它还可以用于格式化输出,以及将列表数据导出到文本文件等。.NET实现List转字符串的方式主要有如下:forLinqString.Join一、Lis... 查看详情

#yyds干货盘点#愚公系列2023年02月.net/c#知识点-list对象去重的方法总结(代码片段)

前言数组去重其实是个很常见的面试题,比如在数据分析中,有时候因为一些原因会有重复的记录,因此需要去重。如果重复的那些行是每一列懂相同的,删除多余的行只保留相同行中的一行就可以了。其实不管前端还是后端,... 查看详情

#yyds干货盘点#愚公系列2023年02月微信小程序-获取wifi信息(代码片段)

前言微信小程序货期WIFI信息主要分为以下几个步骤getSystemlnfo:查看平台环境startWifi:启动WiFi模块getWifiList:尝试拉取WiFi列表onGetWifiList:监听WiFi列表到达connectWifi:连接WiFi一、获取WIFI信息1.全局配置app.js配置"permission":&q... 查看详情

#yyds干货盘点#愚公系列2023年02月.net/c#知识点-区块链概念和实现(代码片段)

前言区块链是一种分布式数据库,使用密码学技术进行安全的数据记录和验证。它可以被用来创建可信赖的记录,并确保记录不可篡改。区块链的原理其实是一个又一个区块组成的链条。每一个区块中保存了一定的信息,它们按... 查看详情

#yyds干货盘点#愚公系列2023年02月.net/c#知识点-efcore性能优化之显示编译(代码片段)

前言性能优化,简而言之,就是在不影响系统运行正确性的前提下,使之运行地更快,完成特定功能所需的时间更短。对于EFCore的查询优化其实也是多种多样的,性能优化是在特定的情况下的特定解决方案,下面着重介绍EFCore的... 查看详情

#yyds干货盘点#愚公系列2023年03月.netcore工具案例-.netcore使用questpdf(代码片段)

前言QuestPDF是一个用于生成PDF文档的open-source.NET库。它提供了一个布局引擎,设计时考虑了完整的分页支持。文档由许多简单元素组成(例如边框、背景、图像、文本、填充、表格、网格等),这些元素组合在一起以创建更复杂... 查看详情

#yyds干货盘点#愚公系列2022年08月go教学课程005-变量(代码片段)

一、变量1.变量的定义变量来源于数学,用于描述计算机中的数据存储空间。变量可以通过变量名访问。在指令式语言中,变量通常是可变的;但在纯函数式语言(如Haskell)中,变量可能是不可变(immutable)的。在一些语言中,... 查看详情

#yyds干货盘点#愚公系列2022年07月go教学课程025-递归函数(代码片段)

一、递归函数如果一个函数在内部调用自身本身,这个函数就是递归函数。递归函数的优点是定义简单,逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。构成递归的条件:子问题须与原... 查看详情

#yyds干货盘点#愚公系列2022年08月go教学课程031-结构体方法(代码片段)

一、结构体方法1.结构体方法的定义方法就是把某些逻辑代码封装到一起的集合,用固定格式包起来起个名字。go中的方法是一个函数,拥有附加的,单独元素的参数列表,称之为接收器。它被放在一个方法名之前。接收器的类... 查看详情

#yyds干货盘点#愚公系列2023年02月.net/c#知识点-委托匿名方法lambda泛型委托表达式树的进化史(代码片段)

前言在.NET中,委托是一种类型,它可以持有对一个或多个方法的引用,并允许将这些方法作为参数传递给其他方法。.NET中的委托类似于C和C++中的函数指针,但具有更高的类型安全性和其他功能。委托的概念最早可以追溯到早期... 查看详情

#yyds干货盘点#愚公系列2022年08月go教学课程035-接口和继承和转换与空接口(代码片段)

一、接口和继承和转换packagemainimport"fmt"typeHumanerinterface SayHello()typePersonerinterface Humaner Say()typeStudentstructfunc(s*Student)SayHello() fmt.Println("大家好")func(s*Student)Say() 查看详情

#yyds干货盘点#愚公系列2022年08月go教学课程022-go容器之字典(代码片段)

一、Go容器之字典1.什么是字典Go中字典也叫做map,map是一种无序的键值对的集合,使用散列表(hash)实现。2.字典的定义var变量名[keyType]valueTypekeyType表示键类型。valueType表示键对应的值类型。2.1第一种使用方式makepackagemainimport"f... 查看详情

#yyds干货盘点#愚公系列2022年08月go教学课程021-go容器之切片操作(代码片段)

一、切片操作1.什么是切片切片和数组类似,都是数据集合。和数组不同的是,切片是一块动态分配大小的连续空间。2.切片的定义2.1切片的格式var变量名[]T//T表示切片类型。相关案例:packagemainimport"fmt"funcmain()//声明整型切片varn... 查看详情

#yyds干货盘点#愚公系列2023年03月.netcore工具案例-stackexchange.redis代码变量方式实现商品秒杀(代码片段)

前言下面是Redis分布式锁常用的概念说明:设置、获取、过期时间、删除。1、Setnx命令:SETNXkeyvalue说明:将key的值设为value,当且仅当key不存在。若给定的key已经存在,则SETNX不做任何动作。SETNX是『SETifNoteXists』(如果不存在,则... 查看详情

#yyds干货盘点#愚公系列2022年09月go教学课程034-接口和多态(代码片段)

一、接口1.接口的定义在生日常活中无时不刻不在使用各种接口,比如电脑的usb,手机的充电接口等等。在计算机程序中接口就是一种规范与标准,只是规定了要做哪些事情,具体怎么做,接口是不管的,接口把所有的具有共性... 查看详情

#yyds干货盘点#愚公系列2022年08月go教学课程027-深拷贝和浅拷贝(代码片段)

一、深拷贝和浅拷贝1.浅拷贝浅拷贝是指对内存地址的复制,让目标对象指针和源对象指向同一片内存空间。go语言中赋值,函数传参,函数返回值都是浅拷贝。packagemainimport"fmt"funcmain()a:=[]string"1","2","3"b:=aa[0]="浅拷贝"fmt.Println("a:",... 查看详情

#yyds干货盘点#愚公系列2022年08月go教学课程002-go语言环境安装(代码片段)

一、Go语言环境安装Go语言是一门编译性的语言需要有SDK工具包对其进行编译才能运行,其次需要有一个编辑工具来写代码,最后为SDK中的工具配置环境变量,所以总结一下可以包含三个方面:SDK工具包安装VSCode安装环境变量配... 查看详情

#yyds干货盘点#愚公系列2022年08月go教学课程032-结构体方法继承(代码片段)

一、结构体方法继承1.继承的概念继承是指一个子类(或称为派生类)继承父类(或称为基类)的特征(属性和操作)。继承是面向对象程序设计时实现代码复用的重要手段,它允许在原有的类的基础上进行扩展,增加功能,这样新产生... 查看详情