Entity Framework的启动速度优化
最近开发的服务放到IIS上寄宿之后,遇到一些现象,比如刚部署之后,第一次启动很慢;程序放置一会儿,再次请求也会比较慢。比如第一个问题,可以解释为初次请求某一个服务的时候,需要把程序集加载到内存中可能比较慢,第二个问题有可能是IIS的线程回收机制导致放置若干长时间,空闲的进程被回收了,再次请求的话可能比较慢。
刚开始的时候没有太在意,但是随着系统的发布,这种初次请求,或者闲置若干时间后第一次请求的漫长等待使得App的体验很差,很多时候App加载好半天数据都没过来。如果前端没处理好,还会导致App的假死。所以就花了点功夫研究下什么原因导致。
刚开始的时候,还以为是WebService的框架出了问题。后面使用App,通过Fiddler看到了,某次请求db.竟然长达6s中,并且每次导致请求超时都出现在db.访问这一块,这显然不正常。早期,我们访问数据库使用的是原始的ADO.NET 执行SQL语句,如果有参数的话,参数化防止SQL注入,然后基本的增删查,通过批量生成存储过程实现,并在底层框架层记录了每次服务的访问语句和次数,这样便于调优。起初认为这样性能是坠吼的,但是随着规模的扩大,效率太低,所以就切换到了Entity Framework上,通过自动生成实体,然后通过LINQ的方式来实现增删改查,这样效率快很多。
意识到是数据访问的问题之后,开始在查找Entity Framework第一次启动比较慢的问题,然后在网上找了一下,发现很多人都遇到过同样的问题。解决方案也比较成熟,比如Pre-Generated Mapping Views,NGen等等,下面就逐个来说明,其实这些在网上也有很多,我这里记录一下作为自己以后备查。
一、Entity Framework初次启动优化
下面提到的方法,有很多需要Entity Framework版本的支持,所以我们在使用Entity Framework的时候,最好使用最新版本。
Pre-Generated Mapping Views
关于使用EntityFramework的注意事项在Performance Considerations for Entity Framework 这篇文章中有详细介绍,其中生成视图操作耗时比较多,在Entity Framework执行查询或者对数据库进行写操作的时候,必须生成一些映射视图来访问数据库,这些映射视图是一系列对数据库中对象的抽象声明,这些数据同时也是app domain的缓存元数据的一部分,在同一应用程序作用域里面,创建多个数据库访问上下文时可以重用这部分对象。因为在第一次查询的时候,生成映射视图是比较耗时的,所以关于这一点,具体的详细操作可以查看msdn上的Pre-Generated Mapping Views,这篇文章提供了两种预先生成映射视图的方法,一种是在Visual Studio中,通过安装EF Power Tools 插件来生成(以下图片,来自msdn)。


这种方式不受EF的版本限制。
网站还提供了第二种通过代码的方式来预先生成视图,这必须要求EF是6.0及以上版本。这也是博客园这篇文章 来,给Entity Framework热热身所使用的方法。一般的,如果是Web站点,可以放在App_Start中来初始化:
protected void Application_Start(object sender, EventArgs e)
{
//预热EntityFramework
using (var dbcontext = new mcccEntities())
{
var objectContext = ((IObjectContextAdapter)dbcontext).ObjectContext;
var mappingCollection = (StorageMappingItemCollection)objectContext.MetadataWorkspace.GetItemCollection(DataSpace.CSSpace);
mappingCollection.GenerateViews(new List<EdmSchemaError>());
}
}
经过以上处理,大概程序初次查询db从之前的6s下降到了3s左右。
除了以上优化之外,对于EF6.0及之后的版本,可以使用NGen处理来进一步提高速度。
二、NGen优化
相关优化可以查看这篇文章Improving Startup Performance with NGen (EF6 Onwards),下面这条方法,主要是针对EF6及以上版本的,因为低于这个版本的自带该特性,在这篇文章里说的很清楚“在6.0之前的EF中,EF的运行时核心类库也是.NET框架的一部分,其本地映像在.NET 核心类库加载时自动加载,在6.0及之后的版本,EF整个运行时已经被集成到EntityFramework NuGet包中,本地映像需要使用NGen工具来生成才能达到类似的效果”。
提到这里,首先要说一下NGen这个工具的作用以及为什么能够加快应用程序的启动性能。.NET 框架支持为托管应用或者程序集生成本地映像文件来帮助应用程序更快启动和在一些情况下减少内存占用。在应用程序执行之前,通过将托管代码程序集翻译为包含本地机器指令的文件,能够减少.NET JIT编译器在应用程序启动的时候,生成本地指令代码这一过程,从而能够加快应用程序启动。
使用NGen也很简单
1:以管理员身份启动控制台cmd程序
2:切换到本机.NET 工具目录下:
对于32位机器,通常在%WINDIR%\Microsoft.NET\Framework\v4.0.30319\下
对于64位机器,通常在 %WINDIR%\Microsoft.NET\Framework64\v4.0.30319\下
3:然后执行 ngen install 加上程序集的路径和名称,即可。
比如在我的机器上,可以看到如下:

经过这一操作,首次访问db的速度终于控制到了500ms以内。
以上是EF的优化,解决了首次部署之后,第一次访问数据库的问题,对于应用程序放置一会儿,再次请求由于线程池回收导致再次访问变慢的问题,通过设置IIS解决。
三、IIS设置
将服务或者站点部署到IIS上之后,在对应的线程池里有两个地方可以设置,如下图:

- 空闲超时时间,默认是20分钟,表示在20分钟之类,如果没有请求进来,那么对应的线程就处于闲置状态,这里将其改为0。
- 例常(Regular)回收时间,这里默认为1740分钟,大概是29个小时(为什么是29而不是24,据说是为了将回收时间的影响减小到最小化,方便调试找到问题,29是24以后的第一个质数),表示大概每隔29个小时,IIS会回收一次应用程序线程池里面的线程。
这样设置之后就可以解决第二个问题。
四、总结
本文简单介绍了优化EntityFramework初次启动速度的方法,以及为防止IIS线程超时闲置,以及例常线程回收导致的初次运行时间过长的解决方法,希望对您解决上述问题有所帮助。
Entity Framework的启动速度优化的更多相关文章
- 记一次Entity Framework 项目的优化过程
在博客园看了不少其他大神的经验.今天也抽空贡献点自己的经验(并不是说自己也是大神..小弟还只新手程序员去年才毕业的) 好了废话不多说,直接进入主题.(具体的好坏各位看官就随便看看吧..没有什么好坏之分 ...
- 开发 ASP.NET vNext 续篇:云优化的概念、Entity Framework 7.0、简单吞吐量压力测试
继续上一篇<开发 ASP.NET vNext 初步总结(使用Visual Studio 2014 CTP1)>之后, 关于云优化和版本控制: 我本想做一下MAC和LINUX的self-ho ...
- Entity Framework 实体框架的形成之旅--利用Unity对象依赖注入优化实体框架(2)
在本系列的第一篇随笔<Entity Framework 实体框架的形成之旅--基于泛型的仓储模式的实体框架(1)>中介绍了Entity Framework 实体框架的一些基础知识,以及构建 ...
- 云优化的概念、Entity Framework 7.0、简单吞吐量压力测试
云优化的概念.Entity Framework 7.0.简单吞吐量压力测试 继续上一篇<开发 ASP.NET vNext 初步总结(使用Visual Studio 2014 CTP1)>之 ...
- Lazy<T>在Entity Framework中的性能优化实践
Lazy<T>在Entity Framework中的性能优化实践(附源码) 2013-10-27 18:12 by JustRun, 328 阅读, 4 评论, 收藏, 编辑 在使用EF的 ...
- [2014-09-18]Entity Framework 6 预热、启动优化
好久没写博客了,终于憋出了一个大招,现在总结下. 虽然文章题目是针对EF的,但涉及的内容不仅仅是EF. 场景介绍 目前在做的一个项目,行业门户,项目部分站点按域名划分如下: user.xxx.com: ...
- Entity Framework 数据并发访问错误原因分析与系统架构优化
博客地址 http://blog.csdn.net/foxdave 本文主要记录近两天针对项目发生的数据访问问题的分析研究过程与系统架构优化,我喜欢说通俗的白话,高手轻拍 1. 发现问题 系统新模块上 ...
- Entity Framework 6 预热、启动优化
虽然文章题目是针对EF的,但涉及的内容不仅仅是EF. 场景介绍 目前在做的一个项目,行业门户,项目部分站点按域名划分如下: user.xxx.com:用户登陆注册 owner.xxx.com:个人用户 ...
- Entity FrameWork 中使用Lambda访问数据库性能优化
在使用Entity Framework 访问数据库时,我们经常使用Lambda表达式,但是如果不小心的话,很容易就掉到坑里了.比如下面的例子:用Lambda访问MSSqlServer中的NewsInf ...
随机推荐
- dubbo服务提供与消费
一.前言 项目中用到了Dubbo,临时抱大腿,学习了dubbo的简单实用方法.现在就来总结一下dubbo如何提供服务,如何消费服务,并做了一个简单的demo作为参考. 二.Dubbo是什么 Dubbo ...
- 苹果强制使用HTTPS传输了怎么办?——关于HTTPS,APP开发者必须知道的事
WeTest 导读 2017年1月1日起,苹果公司将强制使用HTTPS协议传输.本文通过对HTTPS基础原理和通信过程内容的讲解,介绍APP开发者在这个背景下的应对办法. 几周前,我们在<htt ...
- Javascript 代理模式模拟一个文件同步功能
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 破解SQLServer for Linux预览版的3.5GB内存限制 (UBUNTU篇)
在上一篇中我提到了如何破解RHEL上SQLServer的内存大小限制,但是Ubuntu上还有一道检查 这篇我将会讲解如何在3.5GB以下内存的Ubuntu中安装和运行SQLServer for Lin ...
- winform 窗体圆角设计
网上看到的很多winform窗体圆角设计代码都比较累赘,这里分享一个少量代码就可以实现的圆角.主要运用了System.Drawing.Drawing2D. 效果图 代码如下. private void ...
- 【干货分享】流程DEMO-费用报销
流程名: 费用报销 业务描述: 流程发起时,要选择需要关联的事务审批单,会检查是否超申请,如果不超申请,可以直接发起流程,如果超了申请,需要检查预算,如果预算不够,将不允许发起报销申请,如果预算够用, ...
- 基于注解的Spring多数据源配置和使用
前一段时间研究了一下spring多数据源的配置和使用,为了后期从多个数据源拉取数据定时进行数据分析和报表统计做准备.由于之前做过的项目都是单数据源的,没有遇到这种场景,所以也一直没有去了解过如何配置多 ...
- 豪情-CSS解构系列之-新浪页面解构-01
目录: 一. 新浪的布局特点 二. 内容细节的特点 三. 其中相关的一些基础技术点 1. 常见布局方法 2. 布局要点 3. Debugger误区 4.列表 5.字体颜色 6.CSS选择符 7.CSS ...
- 深入浅出聊优化:从Draw Calls到GC
前言: 刚开始写这篇文章的时候选了一个很土的题目...<Unity3D优化全解析>.因为这是一篇临时起意才写的文章,而且陈述的都是既有的事实,因而给自己“文(dou)学(bi)”加工留下的 ...
- 【道德经】漫谈实体、对象、DTO及AutoMapper的使用
写在前面 实体和值对象 实体和对象 故常无欲以观其妙,常有欲以观其徼 初始实体和演化实体 代码中的DTO AutoMapper实体转换 后记 实体(Entity).对象(Object).DTO(Dat ...