zoukankan      html  css  js  c++  java
  • 第八节: EF的性能篇(一) 之 EF自有方法的性能测试

    一. 开发中常见的性能问题

       我们在日常开发过程中,由于一些不好的习惯,经常会导致所写的代码性能低下,却毫无发觉,下面就总结一下常见的一些性能问题。

    1. 真假分页

      ① 假分页: db.xxx.toList().Skip(2).take(4) 。

       ② 真分页:db.xxx.Skip(2).take(3).toList() 。

    2. 合理的使用EF的数据加载方式

       EF的加载方式有:立即加载、延迟加载、显示加载。

      详见:

        ①: 第五节: EF高级属性(一) 之 本地缓存、立即加载、延迟加载(不含导航属性)

        ②: 第六节: EF高级属性(二) 之延迟加载、立即加载、显示加载(含导航属性)

    3. NoTracking的使用

       EF查询出来的实体,默认是跟踪状态的,如果查询出来的实体不需要修改或者删除,查询的时候可以删除状态跟踪,变为Detached状态,来提高性能。

        关于EF状态的跟踪,详见后面章节,敬请期待!!

    1     using (DbContext context = new MyDbContext())
    2     { 
    3          var people = context.Student.Where(p => p.Id > 2).AsNoTracking().ToList();
    4     }

    4. 合理的使用SQL事务

      将与事务无关的一些SQL语句放到事务外,如果一个事务中的SQL语句过长,很容易出现死锁问题,压力测试时,出现资源被锁的错误。

    二. 关于EF数据操作的性能问题

       EF自诞生以来,大批量的操作增加、删除、修改操作数据效率一直很低,1000条数据以内,效率尚且可以接受(10s内),但随着数据量逐渐增大,很容易在执行的过程中就宕机了,相当尴尬。在本章节,我们一起来测试一下,EF在不进行任何优化的情况下,几种写法的效率问题。

      我们这里的测试是以增加数据为例,先把测试的三种写法的结论贴上。

    1. 每添加1条数据,savechange一下(小白常犯的错误,坚决抵制这种做法!!)

     1      private static void NewMethod1(DbContext db)
     2         {
     3             Console.WriteLine("-------------1. 每添加1条数据,savechange一下(小白常犯的错误,坚决抵制这种做法!!)-------------------");
     4             Stopwatch watch = Stopwatch.StartNew();
     5             for (int i = 0; i < 1000; i++)
     6             {
     7                 TestOne t = new TestOne();
     8                 t.id = Guid.NewGuid().ToString("N");
     9                 t.t1 = "t1+" + i;
    10                 t.t1 = "t2+" + i;
    11                 db.Set<TestOne>().Add(t);
    12                 db.SaveChanges();
    13             }
    14             watch.Stop();
    15             Console.WriteLine("1000条数据耗时:{0}", watch.ElapsedMilliseconds);
    16         }

    2. 先将所有数据添加到内存里,最后再savechange

     1  private static void NewMethod2(DbContext db, int count)
     2         {
     3             Console.WriteLine("-------------2. 先将所有数据添加到内存里,最后再savechange-------------------");
     4             Stopwatch watch = Stopwatch.StartNew();
     5             for (int i = 0; i < count; i++)
     6             {
     7                 TestOne t = new TestOne();
     8                 t.id = Guid.NewGuid().ToString("N");
     9                 t.t1 = "t1+" + i;
    10                 t.t1 = "t2+" + i;
    11                 db.Set<TestOne>().Add(t);
    12             }
    13             db.SaveChanges();
    14             watch.Stop();
    15             Console.WriteLine("{0}条数据耗时:{1}", count, watch.ElapsedMilliseconds);
    16         }

    3. 使用addRange方法,先将数据加到list集合中,然后一次性通过addRange加到内存里

     1      private static void NewMethod3(DbContext db, int count)
     2         {
     3             Console.WriteLine("-------------3. 使用addRange方法,先将数据加到list集合中,然后一次性通过addRange加到内存里-------------------");
     4             Stopwatch watch = Stopwatch.StartNew();
     5             List<TestOne> tList = new List<TestOne>();
     6             for (int i = 0; i < count; i++)
     7             {
     8                 TestOne t = new TestOne();
     9                 t.id = Guid.NewGuid().ToString("N");
    10                 t.t1 = "t1+" + i;
    11                 t.t1 = "t2+" + i;
    12                 tList.Add(t);
    13             }
    14             db.Set<TestOne>().AddRange(tList);
    15             db.SaveChanges();
    16             watch.Stop();
    17             Console.WriteLine("{0}条数据耗时:{1}", count, watch.ElapsedMilliseconds);
    18         }

       总结:EF自有的方法,三个阶段如上,数据超过1000条,性能直线下降,那么怎么来解决EF处理大数据量的性能问题呢?敬请期待下一个章节:   第九节: EF的性能篇(二) 之 Z.EntityFramework.Extensions程序集解决EF的性能问题

  • 相关阅读:
    FastApi
    ceph 分布式存储安装
    Linux的inode的理解
    Linux面试题汇总答案
    五,openstack之nova服务的安装(计算节点)
    四,openstack之nova服务的安装(控制节点)
    三,openstack之glance服务的安装
    二,openstack之keystone的简介与安装
    一,openstack基础服务部署
    Kubernetes学习之路(24)之Prometheus监控
  • 原文地址:https://www.cnblogs.com/yaopengfei/p/7751346.html
Copyright © 2011-2022 走看看