实体框架6.2第一次启动和EFInteractiveViews非常慢

问题描述 投票:1回答:2

这个主题已经在stackoverflow和许多其他博客上被广泛讨论过了,提出问题的原因是我观察到这个主题在大多数3到5年的帖子中讨论过,而我们现在有EF 6.2版本,我希望这可能已经有了更新(你会发现有更多的理由。

我的应用程序至少有25个模型(表)与MySQL作为数据库,模型和关系在OnModelCreating配置,网站托管在godaddy,我没有很好的访问IIS配置等。

页面加载时间

  • 首页加载:65到70秒
  • 第2页加载:1到3秒

再延迟10分钟后,加载页面需要70秒。请注意,我在不同的环境中测试它,例如使用不同的互联网连接。页面上没有图片,测试页面只有5行数据,有两列(调用简单方法db.Test.ToList();)

在搜索互联网时,我发现这是EF的常见问题所以我尝试修复它,同时从帖子3 Steps for Fast EntityFrameworkPregenerate Model and View Cache获取帮助

这个修复后

  • 首页加载:64到67秒
  • 第2页加载:1到3秒 // DbConfiguration constructor public MyDbConfiguration { var path = Path.GetDirectoryName(this.GetType().Assembly.Location); SetModelStore(new DefaultDbModelStore(path)); } // DbContext private static DbMappingViewCacheFactory viewCacheFactory; private static DbMappingViewCacheFactory ViewCacheFactory { get { if (viewCacheFactory == null) { var path =ConfigurationManager.AppSettings[GlobalContextConfig.EFCacheFolder]; viewCacheFactory=new FileViewCacheFactory(path+"Budget.Context.MyDbContext.xml"); } return viewCacheFactory; } } public MyDbContext() : base("name=MySqlConnectionString") { // In case i need to update xml for now i delete the old file manually InteractiveViews.SetViewCacheFactory(this, ViewCacheFactory); Database.SetInitializer<MyDbContext>(null); this.Configuration.ProxyCreationEnabled = false; this.Configuration.LazyLoadingEnabled = false; this.Configuration.AutoDetectChangesEnabled = false; this.Configuration.ValidateOnSaveEnabled = false; }

它有所改进,但还不够,我想知道这些问题是否在EF 6.2.0中更新或修复它的方法已经改变,或者我做错了什么/应该检查。

我还安装了EF 6.1.X并通过右键单击Contaxt文件并在manu中选择Entity Framework> Generate View来生成视图

结果:

  • 首页加载:40到50秒
  • 第2页加载:0到1.5秒

令人惊讶的是,EF 6.1.X比EF 6.2快得多

使用debug = false构建和部署为Release包

出于测试目的,我还上传了没有Entity Framework的asp.net应用程序,第一次加载需要8到13秒,第二次加载需要不到1秒

asp.net-mvc entity-framework entity-framework-6 linq-to-entities
2个回答
2
投票

我想知道这些问题是否在EF 6.2.0中更新或修复它的方法已经改变,或者我做错了什么/应该检查。

答案是肯定的,

EF 6.2引入了模型缓存

public class MyDbConfiguration : DbConfiguration
{
    public MyDbConfiguration() : base()
    {
        var path = Path.GetDirectoryName(this.GetType().Assembly.Location);
        SetModelStore(new DefaultDbModelStore(path));
    }
}

[DbConfigurationType(typeof(MyDbConfiguration))]
public class MyContextContext : DbContext 
{
}

你可以在这里了解更多:https://codeopinion.com/entity-framework-code-first-model-cache/


0
投票

我假设您已阅读性能注意事项:

https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/ef/performance-considerations

我个人也在努力解决这些问题。我使用了a) creating custom SQL for some queries。 b)我创建了一个预热机制。还可以选择预编译可能有帮助的查询。

预热机制在应用程序启动时在单独的线程上运行。它向数据库发出一个非常简单的请求,这会强制创建模型,并“触发”所有查询的初始启动延迟。在该查询运行之后(需要几秒钟),标志被设置。所有其他操作在运行之前等待标志设置。特别是在多线程场景中,这有很大帮助。

我发现每个线程都创建了启动延迟。这意味着如果延迟让我们说2秒,运行3个线程,他们都创建一个上下文并尝试运行一些linq,使整个应用程序等待6秒。

请注意,通过创建自定义查询,必须返回要创建的实体的所有字段;

    var blogs = context.Blogs.SqlQuery("SELECT * FROM dbo.Blogs").ToList(); //works
    var blogs = context.Blogs.SqlQuery("SELECT [id] FROM dbo.Blogs").ToList(); //Does not.

我没有完全测试过这个问题 - 所以需要一些时间来测试。这只是一个抬头。

© www.soinside.com 2019 - 2024. All rights reserved.