刚开始的时候没有太在乎,可是随着系统的发布,这种初次请求,或者闲置若干时间后第一次请求的漫长等待使得App的体验不好,不少时候App加载好半天数据都没过来。若是前端没处理好,还会致使App的假死。因此就花了点功夫研究下什么缘由致使。html
刚开始的时候,还觉得是WebService的框架出了问题。后面使用App,经过Fiddler看到了,某次请求db.居然长达6s中,而且每次致使请求超时都出如今db.访问这一块,这显然不正常。早期,咱们访问数据库使用的是原始的ADO.NET 执行SQL语句,若是有参数的话,参数化防止SQL注入,而后基本的增删查,经过批量生成存储过程实现,并在底层框架层记录了每次服务的访问语句和次数,这样便于调优。起初认为这样性能是坠吼的,可是随着规模的扩大,效率过低,因此就切换到了Entity Framework上,经过自动生成实体,而后经过LINQ的方式来实现增删改查,这样效率快不少。前端
意识到是数据访问的问题以后,开始在查找Entity Framework第一次启动比较慢的问题,而后在网上找了一下,发现不少人都遇到过一样的问题。解决方案也比较成熟,好比Pre-Generated Mapping Views,NGen等等,下面就逐个来讲明,其实这些在网上也有不少,我这里记录一下做为本身之后备查。数据库
下面提到的方法,有不少须要Entity Framework版本的支持,因此咱们在使用Entity Framework的时候,最好使用最新版本。缓存
Pre-Generated Mapping Viewsapp
关于使用EntityFramework的注意事项在Performance Considerations for Entity Framework 这篇文章中有详细介绍,其中生成视图操做耗时比较多,在Entity Framework执行查询或者对数据库进行写操做的时候,必须生成一些映射视图来访问数据库,这些映射视图是一系列对数据库中对象的抽象声明,这些数据同时也是app domain的缓存元数据的一部分,在同一应用程序做用域里面,建立多个数据库访问上下文时能够重用这部分对象。由于在第一次查询的时候,生成映射视图是比较耗时的,因此关于这一点,具体的详细操做能够查看msdn上的Pre-Generated Mapping Views,这篇文章提供了两种预先生成映射视图的方法,一种是在Visual Studio中,经过安装EF Power Tools 插件来生成(如下图片,来自msdn)。框架
这种方式不受EF的版本限制。dom
网站还提供了第二种经过代码的方式来预先生成视图,这必需要求EF是6.0及以上版本。这也是博客园这篇文章 来,给Entity Framework热热身所使用的方法。通常的,若是是Web站点,能够放在App_Start中来初始化:ide
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处理来进一步提升速度。post
相关优化能够查看这篇文章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上以后,在对应的线程池里有两个地方能够设置,以下图:
这样设置以后就能够解决第二个问题。
本文简单介绍了优化EntityFramework初次启动速度的方法,以及为防止IIS线程超时闲置,以及例常线程回收致使的初次运行时间过长的解决方法,但愿对您解决上述问题有所帮助。