EF Core的性能优化

目录​​​​​​​

一、EF Core的性能之AsNoTracking

二、Find和FindAsync方法

三、全局查询筛选器

四、悲观并发控制

五、乐观并发控制


一、EF Core的性能之AsNoTracking

     EF Core 默认会对通过上下文查询出来的所有实体类进行,以便于在执行 SaveChanges 的时候把实体类的改变同步到数据库中。上下文不仅会跟踪对象的状态改变,还会通过快照的方式记录实体类的原始值,这是比较消耗资源的。因此,如果开发人员能够确认通过上下文查询出来的对象只是用来展示,不会发生状态改变,那么可以使用AsNoTracking 方法告诉IQueryable 在查询的时候“禁用跟踪”。

Book[] books=ctx.Books,AsNoTracking()Take(3).ToArray();
Book bl=books[0];
bl.Title="abc";
EntityEntry entryl = ctx.Entry(bl);
Console.WriteLine(entryl.State);

上面代码的执行结果是“Detached”,也就说使用AsNoTracking 查询出来的实体类是不被上下文跟踪的。因此,在项目开发的时候,如果我们查询出来的对象不会被修改、删除等,那么在查询的时候,可以启用AsNoTraking,这样就能降低EF Core的资源占用。

二、Find和FindAsync方法

当使用EF Core 从数据库中根据 Id 获取数据的时候,我们还可以使用同步的Fid 方法或者异步的FindAsync法。Find或者FindAsync方法会先在上下文查找这个对象是否已经被跟如果对象已经被跟踪,就直接返回被跟踪的对象,只有在本地没有找到这个对象时,EF Core才去数据库查询,而Single方法则一直都是执行一次数据库查询。因此用Find 方法有可能少一次数据库查询,性能更好。但是如果在对象被跟踪之后,数据库中对应的数据已经被其程序修改了,则Find方法可能会返回旧数据

三、全局查询筛选器

在EFCore 中,我们可以给对应实体类设置一个全局查询筛选器,这样所有的查询都会自动增加全局查询筛选器,被软删除的数据就会自动从查询结果中过滤掉。全局查询筛选器可以让开发人员专注于编写业务逻辑代码,而不用操心软删除数据的滤。当然,使用软删除的时候,我们需要注意其对性能的影响。如果启用了软删除,查询餐可能会导致全表扫描,从而影响查询性能,而如果为软删除列创建索引的话,又会增加索引“磁盘占用。正因为如此,如果使用了全局查询筛选器,我们就需要根据项目的需要进一步优化数据库。

四、悲观并发控制

为了避免多个用户同时操作资源造成的并发冲突问题,我们通常会进行并发控制。并发控制有很多种实现方式,在数据库层面有“悲观”和“乐观”两种策略。悲观并发控制一般采用行锁、表锁等排他锁对资源进行锁定,确保同时只有一个使用者操作被锁定的资源:乐观并发控制则允许多个使用者同时操作同一个资源,通过冲突的检测避免并发操作。

因为不同类型的数据库对于悲观并发控制的实现差异很大,所以EFCore 没有封装悲观发控制,需要开发人员编写原生 SQL 语句。

悲观并发控制的使用比较简单,只要对要进行并发控制的资源加上锁即可。但是这种锁是独占排他的,如果系统并发量很大,锁会严重影响性能,如果使用不当,甚至会导致死锁。因机,这里只是用1s此,对于高并发系统,要尽量优化算法,比如调整逻辑或者使用 NoSQL 等,尽量避免通过关系数据库进行并发控制。如果必须使用数据库进行并发控制,尽量采用乐观并发控制。

五、乐观并发控制

EF Core 内置了使用并发令牌列实现的乐观并发控制,乐观并发控制能够避免悲观锁带来的性能下降、死锁等问题,因此作者推荐使用乐观并发控制而不是悲观锁。如果有一个确定的字段要被进行并发控制,使用ISConcurrencyToken 把这个字段设置为并发令牌即可;如果无法确定唯一的并发令牌列,可以引入一个额外的属性并将其设置为并发令牌,并且在每次更新数据的时候,手动更新这一列的值:当然,如果用的是Microson soL Server 数据库,我们也可以采用 RowVersion 列,这样就不用开发人员手动更新并发令牌列的值了。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
EF6 是 Entity Framework 6 的简称,它是微软开发的一种对象关系映射(ORM)工具。T-SQL 是 Transact-SQL 的简称,是一种用于 SQL Server 数据库的查询语言。 在 EF6 查询性能和 T-SQL 对比方面,有以下几点需要考虑: 1. 执行计划:EF6 会将 LINQ 查询转换为相应的 SQL 查询语句,然后由数据库服务器执行。而 T-SQL 直接在数据库服务器上执行,因此在执行计划的生成和优化方面,T-SQL 通常更加高效。 2. 数据库适应性:T-SQL 可以充分利用数据库的特性和优化策略,如索引、分区等。而 EF6 在生成 SQL 查询语句时,可能无法充分利用数据库的特性,导致性能较低。 3. 缓存机制:EF6 提供了查询结果的缓存机制,可以在一定程度上提高查询性能。而 T-SQL 没有内置的缓存机制,需要手动实现。 4. 查询表达能力:EF6 使用 LINQ 查询语法,提供了强类型的查询表达能力,可以更加直观和灵活地进行查询。而 T-SQL 的查询表达能力相对较弱,需要手动编写 SQL 查询语句。 综上所述,EF6 在查询性能方面可能不如 T-SQL,特别是在复杂查询和大数据量的情况下。如果对性能要求较高,可以考虑直接使用 T-SQL 编写查询语句。但是,EF6 提供了更方便和灵活的开发方式,并且在简单查询和开发效率方面具有优势。所以,在选择使用 EF6 还是 T-SQL 时,需要根据具体场景和需求进行权衡。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

咬口大葱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值