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 ...
随机推荐
- Android Ormlite 学习笔记1 -- 基础
Ormlite 是一个开源Java数据实体映射框架.其中依赖2个核心类库: 1.ormlite-android-4.48.jar 2.ormlite-core-4.48.jar 新建项目,引用上面2个 ...
- Vue-Router 页面正在加载特效
Vue-Router 页面正在加载特效 如果你在使用 Vue.js 和 Vue-Router 开发单页面应用.因为每个页面都是一个 Vue 组件,你需要从服务器端请求数据,然后再让 Vue 引擎来渲染 ...
- C++中的const
一,C++中const的基本知识 1.C++中const的基本概念 1.const是定义常量的关键字,表示只读,不可以修改. 2.const在定义常量的时候必须要初始化,否则报错,因为常量无法修改,只 ...
- 来吧,HTML5之基础标签(下)
<dialog> 标签 定义对话框或窗口. <dialog> 标签是 HTML 5 的新标签.目前只有 Chrome 和 Safari 6 支持 <dialog> ...
- VSCode调试go语言出现:exec: "gcc": executable file not found in %PATH%
1.问题描述 由于安装VS15 Preview 5,搞的系统由重新安装一次:在用vscdoe编译go语言时,出现以下问题: # odbcexec: "gcc": executabl ...
- ubuntu下配置vimtab空格数
vim ~/.vimrc 没有就创建 set tabstop=4 //4就是4个空格
- 萌新笔记——linux下查看内存的使用情况
windows上有各种软件可以进行"一键加速"之类的操作,释放掉一些内存(虽然我暂时不知道是怎么办到的,有待后续学习).而任务管理器也可以很方便地查看各进程使用的内存情况,如下图: ...
- 【Knockout.js 学习体验之旅】(2)花式捆绑
本文是[Knockout.js 学习体验之旅]系列文章的第2篇,所有demo均基于目前knockout.js的最新版本(3.4.0).小茄才识有限,文中若有不当之处,还望大家指出. 目录: [Knoc ...
- [ 技术人员创业Tips ] 1:抓住优质客户(上)
写一篇技术以外的内容,可能会得罪一些人,轻拍,此外本文写的比较随意,写到哪里算哪里,轻拍. IT业不知道从什么时候起特别流行谈创业,似乎不谈创业就落伍,我不评价这种风气的好坏,只提一些自己的一些经验和 ...
- Unity3D和Egret3D的基情
Unity3D依靠多平台发布这个核心特点,目前如日中天,屌丝引擎之王绝无来者.Egret白鹭引擎,也着实在微信上刷了一屏又一屏.这二者似乎风马牛不相及,但是这个无处不搞基的年代,让一切皆有可能. U3 ...