第九节: EF的性能篇(二) 之 Z.EntityFramework.Extensions程序集解决EF的性能问题

时间:2022-09-26 09:17:27

一. 综述

  该模块主要介绍:EF的性能优化插件Z.EntityFramework.Extensions,该插件收费

(一). 简介

1. 相关网站:http://www.zzzprojects.com/

2. 下载途径:通过Nuget直接下载或者去官网下载(要注意更新最新版本,可能会过期)

3. 该程序集包括三个核心模块:Bulk SaveChanges、Bulk Operations、Batch Operations

(二).Bulk SaveChanges 大批量保存

1. 核心方法:BulkSaveChanges

2. 该方法是在EF原有方法SaveChanges方法上的一个提升。

3. 使用方法:增删改操作均使用EF自有的方式,最后事务性提交数据库,BulkSaveChanges代替SaveChanges

4. 工作原理:与SaveChanges类似,但是减少了与数据库的往返次数,从而提高了性能

5. 性能测试:以增加数据为例进行测试:

1000条    5000条    10000条

1.606s    6.542s      21.857s

6. 可配置参数 (改变这两个参数对性能影响不大)

①.BatchSize 批量提交块的大小

②.AllowConcurrency 是否允许并发检查

(三). Bulk Operations

1. 核心方法:BulkInsert(增加)、BulkDelete(删除)、BulkUpdate(修改)、BulkMerge(合并)、BulkSynchronize(同步)

其中:BulkMerge(合并)、BulkSynchronize(同步)不常用,这里不单独测试了。 (根据传入的类型可以直接找到对应的表进行操作)

2. 工作原理:尽可能的减少与数据库的往返次数,

3. 性能测试:BulkInsert性能进行测试:

  1000条    5000条    10000条    40000条

  1.432s    1.568s      1.554s    1.899s

4. 性能测试:BulkDelete性能进行测试:

  1000条    5000条    10000条    40000条

  1.430s    1.542s       1.540s      2.597s

5. 可配置参数 (改变这两个参数对性能影响不大)

①.BatchSize 批量提交块的大小

②.AllowConcurrency 是否允许并发检查

(四). Batch Operations (批量进行统一操作)

1. 核心方法:DeleteFromQuery、UpdateFromQuery

2. 使用方法:

①. context.Customers.Where(x => x.ID == userId).DeleteFromQuery();

②. context.Customers.Where(x => x.ID == userId).UpdateFromQuery(x => new Customer {Actif = false});

3. 性能测试: DeleteFromQuery的性能测试

  1000条    5000条    10000条    40000条

  0.1s      0.127s   0.156s         0.490s

4. 性能测试: UpdateFromQuery的性能测试

  1000条    5000条    10000条    40000条

  0.120s    0.131s       0.172s      0.437s

二. 代码实战

1. 1.以增加数据为例,进行测试BulkSaveChanges(测试数据条数:1000,5000,10000)

  private static void NewMethod1(DbContext db, int count)
{
Console.WriteLine("-------------1. 提供BulkSaveChanges方法来替代EF本身的Savechanges------------------");
Stopwatch watch = Stopwatch.StartNew();
for (int i = ; i < count; i++)
{
TestTwo t = new TestTwo();
t.id = Guid.NewGuid().ToString("N");
t.t21 = "t1+" + i;
t.t22 = "t2+" + i;
db.Set<TestTwo>().Add(t);
} db.BulkSaveChanges(); //db.BulkSaveChanges(options =>
//{
// options.BatchSize = 1000;
// options.AllowConcurrency = false;
//});
watch.Stop();
Console.WriteLine("{0}条数据耗时:{1}", count, watch.ElapsedMilliseconds);
}

2. 以增加为例,测试BulkInsert方法(测试数据条数:1000,5000,1w,4w)

   private static void NewMethod2(DbContext db, int count)
{
Console.WriteLine("-------------1. 以增加为例,测试BulkInsert方法(测试数据条数:1000,5000,1w,4w)------------------");
Stopwatch watch = Stopwatch.StartNew();
List<TestTwo> list = new List<TestTwo>();
for (int i = ; i < count; i++)
{
TestTwo t = new TestTwo();
t.id = Guid.NewGuid().ToString("N");
t.t21 = "t1+" + i;
t.t22 = "t2+" + i;
list.Add(t);
} db.BulkInsert(list); //db.BulkInsert(list, p =>
//{
// p.BatchSize = 100;
// p.AllowConcurrency = false;
//});
watch.Stop();
Console.WriteLine("{0}条数据耗时:{1}", count, watch.ElapsedMilliseconds);
}

3. 以删除为例,测试BulkDelete方法(测试数据条数:1000,5000,1w,4w)

 private static void NewMethod3(DbContext db, int count)
{
Console.WriteLine("-------------2. 以删除为例,测试BulkDelete方法(测试数据条数:1000,5000,1w,4w)------------------");
Stopwatch watch = Stopwatch.StartNew();
List<TestTwo> list = db.Set<TestTwo>().Take(count).ToList();
db.BulkDelete(list);
watch.Stop();
Console.WriteLine("{0}条数据耗时:{1}", count, watch.ElapsedMilliseconds);
}

4. DeleteFromQuery的性能测试(测试数据条数:1000,5000,1w,4w)

    private static void NewMethod4(DbContext db, int count)
{
Console.WriteLine("-------------1. DeleteFromQuery的性能测试(测试数据条数:1000,5000,1w,4w)------------------");
Stopwatch watch = Stopwatch.StartNew();
db.Set<TestTwo>().Where(u=>u.id!="fk").DeleteFromQuery(); watch.Stop();
Console.WriteLine("{0}条数据耗时:{1}", count, watch.ElapsedMilliseconds);
}

5. UpdateFromQuery的性能测试(测试数据条数:1000,5000,1w,4w)

 private static void NewMethod5(DbContext db, int count)
{
Console.WriteLine("-------------2. UpdateFromQuery的性能测试(测试数据条数:1000,5000,1w,4w)------------------");
Stopwatch watch = Stopwatch.StartNew();
db.Set<TestTwo>().Where(u => u.id != "fk").UpdateFromQuery(x => new TestTwo {
t21="",
t22=""
}); watch.Stop();
Console.WriteLine("{0}条数据耗时:{1}", count, watch.ElapsedMilliseconds);
}

第九节: EF的性能篇(二) 之 Z.EntityFramework.Extensions程序集解决EF的性能问题的更多相关文章

  1. 第二十三节&colon; EF性能篇&lpar;三&rpar;之基于开源组件 Z&period;EntityFrameWork&period;Plus&period;EF6解决EF性能问题

    一. 开篇说明 EF的性能问题一直以来经常被人所吐槽,究其原因在于“复杂的操作在生成SQL阶段耗时长,且执行效率不高”,但并不是没有办法解决,从EF本身举几个简单的优化例子: ①:如果仅是查询数据,并 ...

  2. 【EF】解决EF批量操作,Z&period;EntityFramework&period;Extensions 过期方案

    方案一: 使用EntityFramework.Extended优点: 启下载量是Z.EntityFramework.Extensions的10倍+ 不会过期缺点:不能批量Insert 方案二:解决批量 ...

  3. EF批量插入数据(Z&period;EntityFramework&period;Extensions)

    EF用原生的插入数据方法DbSet.ADD()和 DbSet.AddRange()都很慢.所以要做大型的批量插入只能另选它法. 1.Nugget 2.代码 using EF6._0Test.EF; u ...

  4. 第八节&colon; EF的性能篇&lpar;一&rpar; 之 EF自有方法的性能测试

    一. 开发中常见的性能问题 我们在日常开发过程中,由于一些不好的习惯,经常会导致所写的代码性能低下,却毫无发觉,下面就总结一下常见的一些性能问题. 1. 真假分页 ① 假分页: db.xxx.toLi ...

  5. 第九节:基于MVC5&plus;AutoFac&plus;EF&plus;Log4Net的基础结构搭建

    一. 前言 从本节开始,将陆续的介绍几种框架搭建组合形式,分析每种搭建形式的优势和弊端,剖析搭建过程中涉及到的一些思想和技巧. (一). 技术选型 1. DotNet框架:4.6 2. 数据库访问:E ...

  6. ASP&period;NET MVC深入浅出(被替换) 第一节&colon; 结合EF的本地缓存属性来介绍【EF增删改操作】的几种形式 第三节&colon; EF调用普通SQL语句的两类封装(ExecuteSqlCommand和SqlQuery &rpar; 第四节&colon; EF调用存储过程的通用写法和DBFirst模式子类调用的特有写法 第六节&colon; EF高级属性&lpar;二&rpar; 之延迟加载、立即加载、显示加载&lpar;含导航属性&rpar; 第十节&colon; EF的三种追踪

    ASP.NET MVC深入浅出(被替换)   一. 谈情怀-ASP.NET体系 从事.Net开发以来,最先接触的Web开发框架是Asp.Net WebForm,该框架高度封装,为了隐藏Http的无状态 ...

  7. Redis性能篇(二)CPU核和NUMA架构的影响

    Redis被广泛使用的一个很重要的原因是它的高性能.因此我们必要要重视所有可能影响Redis性能的因素.机制以及应对方案.影响Redis性能的五大方面的潜在因素,分别是: Redis内部的阻塞式操作 ...

  8. 【朝花夕拾】Android性能篇之(七)Android跨进程通信篇

    前言 只要是面试高级工程师岗位,Android跨进程通信就是最受面试官青睐的知识点之一.Android系统的运行由大量相互独立的进程相互协助来完成的,所以Android进程间通信问题,是做好Andro ...

  9. 【朝花夕拾】Android性能篇之(六)Android进程管理机制

    前言        Android系统与其他操作系统有个很不一样的地方,就是其他操作系统尽可能移除不再活动的进程,从而尽可能保证多的内存空间,而Android系统却是反其道而行之,尽可能保留进程.An ...

随机推荐

  1. poj2369 Permutations ——置换群

    link:http://poj.org/problem?id=2369 置换群,最简单的那种. 找所有数字循环节的最小公倍数. /* ID: zypz4571 LANG: C++ TASK: perm ...

  2. 批量Load&sol;Store指令的寻址方式

    批量Load/Store指令用于实现在一组寄存器和一块连续的内存单元之间传输数据.也称为多寄存器寻址方式,即一条指令可以完成多个寄存器值的传送.这种寻址方式可以用一条指令最多完成传送16个通用寄存器的 ...

  3. swift 闭包&plus;嵌套函数&plus;extension&plus;单例&plus;嵌套函数&plus;&quest;&quest;

    //: Playground - noun: a place where people can play import UIKit //*******************嵌套函数********* ...

  4. LNMP1&period;2一键安装教程

    系统需求: CentOS/RHEL/Fedora/Debian/Ubuntu/Raspbian Linux系统 需要2GB以上硬盘剩余空间 128M以上内存,Xen的需要有SWAP,OpenVZ的另外 ...

  5. 运用MyEclipse插件(link方式注意点)

    Windows7 中 MyEclipse 安装位置下,有以下两个目录: MyEclipse 10 Common 注意点一 Common 下的子目录是 plugins 和 features : 而在 M ...

  6. SharePoint Server 2010 删除Web应用

    SharePoint Server 2010 删除Web应用         因为之前的测试.在SharePointserver创建于非常多Web应用(我是在本机Win7系统上安装的SharePoin ...

  7. SSH 之 Spring的源码&lpar;一&rpar;——Bean加载过程

    看看Spring的源码,看看巨人的底层实现,拓展思路,为了更好的理解原理,看看源码,深入浅出吧.本文基于Spring 4.0.8版本. 首先Web项目使用Spring是通过在web.xml里面配置 o ...

  8. Java之mybatis详解

    文章大纲 一.mybatis介绍二.mybatis代码实战三.项目源码下载四.参考文章   一.mybatis介绍 1. mybatis是什么?   mybatis是一个持久层的框架,是apache下 ...

  9. 如何优雅打印nginx header和body

    场景 参考https://segmentfault.com/a/1190000000606867可以获取response的报文体,由于业务测试有获取响应头Header或响应体Body的需求,这里是通过 ...

  10. 使用antd-mobile的ImagePicker组件实现图片的上传

    这篇文章主要是记录一下在开发钉钉微应用时,实现图片上传及显示功能的过程. 这个项目用的dingyou-dingtalk-mobile这个脚手架,可直接在NowaGui上创建.这是一个关于钉钉微应用的脚 ...