实体框架6.2首次启动和EFInteractiveViews速度非常慢

时间:2018-09-17 22:27:20

标签: asp.net-mvc entity-framework entity-framework-6 linq-to-entities

这个话题已经在stackoverflow和许多其他博客上进行了广泛讨论,问这个问题的原因是我观察到这个话题主要是在3到5年的旧帖子中讨论的,而我们现在拥有EF 6.2版本,并且我希望这可能已经更新(有更多原因会引起您的疑问。

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

页面加载时间

  • 首页加载时间:65至70秒
  • 第二页加载时间:1到3秒

再次延迟10分钟后,将需要70秒来加载页面。 请注意,我在不同的环境(例如使用不同的Internet连接)中对其进行了测试。 该页面上没有图片,并且测试页面只有5行数据和两列(调用简单方法db.Test.ToList();)

搜索互联网时,我发现EF普遍存在问题,因此我尝试修复它,同时从帖子3 Steps for Fast EntityFrameworkPregenerate Model and View Cache寻求帮助

此修复程序之后

  • 首页加载时间:64到67秒
  • 第二页加载时间: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文件并在手册中选择“实体框架”>“生成视图”来生成视图

结果:

  • 首页加载:40到50秒
  • 第二页加载时间:0到1.5秒

那真是太神奇了,EF 6.1.X比EF 6.2快得多

使用debug = false

构建并部署为发布包

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

2 个答案:

答案 0 :(得分: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/

答案 1 :(得分: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.

我尚未对此问题进行全面测试-请花一些时间进行测试。这只是一个提示。