记一次Entity Framework 项目的优化过程

在博客园看了不少其他大神的经验。今天也抽空贡献点自己的经验(并不是说自己也是大神。。小弟还只新手程序员去年才毕业的)

好了废话不多说,直接进入主题。(具体的好坏各位看官就随便看看吧。。没有什么好坏之分,纯粹只是一次优化过程的经历。)

首先介绍下项目背景

为某政府单位做的项目,市级的。

用的是Entity Framework 的框架(具体内部如何,不便透露,尽请谅解)

然后说下数据量 大概8W家企业数据,

每家企业大概会有1-2条记录

然后对这部分数据进行报表统计

一共需要统计8个类型的数据

大致表格就是14行8列的数据

然后我们对于每个单元格的数据 都要去读取一下 数据库。

具体请参照代码

public DataTable mytestMethod(DateTime dtbegintime, DateTime dtendtime)
   {
       DataTable dt = new DataTable();
       dt.Columns.Add("ID", typeof(string));
       dt.Columns.Add("1", typeof(string));
       dt.Columns.Add("2", typeof(string));
       dt.Columns.Add("3", typeof(string));
       dt.Columns.Add("4", typeof(string));
       dt.Columns.Add("5", typeof(string));
       dt.Columns.Add("6", typeof(string));
       dt.Columns.Add("7", typeof(string));
       dt.Columns.Add("8", typeof(string));
       List<区> qus = Content.QuServices.GetList();
      foreach( qu in qus)
          {
               datarow dr=dt.newrow();
       dr["1"]=获取的数据.count;
       ......
       .......
       dr["8"]=获取的数据.count;
 
                      dt.Rows.Add(dr);
 
 
          };
       dt.DefaultView.Sort = "1";
       dt = dt.DefaultView.ToTable();
       return dt;
   }

  

我们对于每张表 都只能获取这个表的实体。无法做到组合操作

例如 班级表 学生表  爱好表

就只能获取 list<班级>或者 list<学生>

如果学生里面有部分属性需要使用爱好表的操作的话

就是用懒加载的 学生表。爱好表.属性  来操作

 

第一个版本的 结果就是 我们可能只是用到  查询出来 的学生表 的个数就够了

但是我们获取过来的却是list<学生表>然后 list<学生表>.count 来获取个数。

这样的话 从各方面考虑都大大制约了速度。

 

后来我就想到了用分页的方法

我们底层会有一个分页方法

pageData 类型

包含两个属性 一个 是totalCount(总数) 一个datalist(分页部分的数据)

 

然后我就想到利用分页获取 也就出些了下面这部分代码

 

public DataTable mytestMethod(DateTime dtbegintime, DateTime dtendtime)
     {
         DataTable dt = new DataTable();
         dt.Columns.Add("ID", typeof(string));
         dt.Columns.Add("1", typeof(string));
         dt.Columns.Add("2", typeof(string));
         dt.Columns.Add("3", typeof(string));
         dt.Columns.Add("4", typeof(string));
         dt.Columns.Add("5", typeof(string));
         dt.Columns.Add("6", typeof(string));
         dt.Columns.Add("7", typeof(string));
         dt.Columns.Add("8", typeof(string));
         List<区> qus = Content.QuServices.GetList();
        foreach( qu in qus)
            {
                 datarow dr=dt.newrow();
         dr["1"]=获取分页的数据.totalCount;//分页的pagesize 和pageindex 都传1
         ......
         .......
         dr["8"]=获取分页的数据.totalCount;
 
                        dt.Rows.Add(dr);
 
 
            };
         dt.DefaultView.Sort = "1";
         dt = dt.DefaultView.ToTable();
         return dt;
     }

  

 大致就是利用分页的方法 获取数据的时候只获取 1,1 的数据

这样即可以得到总数又简化了数据量

效果的话并是特别明显但也快了大概4秒的样子。。原先是17秒的 现在要13秒左右

当然这肯定是不行的

然后我导师就让我用Parallel.ForEach 来代替 forearch方法。

这会速度提升非常明显,大概提升了 一倍吧。原先13秒的速度 如今只用 6秒左右了 。但是偶尔会7-8秒的样子

另外发现parallel 非常吃性能。。如果多刷几次的话 貌似就会悲剧掉。

至于Parallel的用法 ,大家可以自己百度一下。

这边需要注意的是 parallel 是并行处理。所以做运算的时候需要注意下 ,不然数据很容易出错。

 

 

最后发现显然还是用SQL 直接组合起来查询比较好。

因为不管老的怎么并行处理 到最后他都是会做14*8=112 次数据查询操作。

所以最后只能继续苦逼的写SQL 组合查询 了。

速度的话 从6秒优化到了3秒 。

本来以为使用了我们的框架就可以脱离sql语句的编写了。没想到最后还是回归了SQL的怀抱。。

哎。。第一次写这种经验类的文章

文章写的很乱。可能很多人看不懂吧,希望大家见谅。

如果发现看到最后是浪费大家的时间 还请各位大神息怒息怒。

最后总结下 就是 从foreach 到parallel 到 SQL的过程

 

 

 

 

 

 

 

posted @   公羽翁  阅读(2133)  评论(4编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
点击右上角即可分享
微信分享提示