首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >mvc-mini-profiler降低实体框架速度

mvc-mini-profiler降低实体框架速度
EN

Stack Overflow用户
提问于 2011-06-23 20:29:36
回答 2查看 1.3K关注 0票数 12

我已经在我的实体框架驱动的MVC3站点上设置了mvc-mini-profiler。一切都进行了适当的配置;在Application_Start中开始分析,在Application_End中结束分析,等等。分析部分工作得很好。

但是,当我尝试将数据模型对象生成转换为提供可分析版本时,性能会变得非常慢。不是每个SQL查询,但有些查询需要大约5倍的整个页面加载。(启动IIS Express后的第一个页面加载花费的时间稍长一些,但这是持续的。)

查询、执行和“读取”SQL的时间可以忽略不计(最多2毫秒),而下面这行代码:

代码语言:javascript
复制
var person = dataContext.People.FirstOrDefault(p => p.PersonID == id);

using(profiler.Step())中封装的...when记录为300-400ms。我向dotTrace进行了分析,它确认了时间实际上是像往常一样在EF中花费的(可分析的组件确实会非常短暂地出现),只是花费的时间要长得多。

这让我相信连接或它的一些组成部分缺少足够的数据,使EF的性能变得更差。

这是我用来创建context对象的方法(我的edmx模型的类名为DataContext):

代码语言:javascript
复制
var conn = ProfiledDbConnection.Get(
    /* returns an SqlConnection */CreateConnection());
return CreateObjectContext<DataContext>(conn);

我最初使用的是mvc-mini-profiler提供的ObjectContextUtils.CreateObjectContext方法。我深入研究它,注意到它设置了一个通配符元数据工作区路径字符串。由于我使用代码将数据库层隔离到一个项目和几个MVC站点作为其他项目,因此这些路径已经更改,我更愿意更具体。另外,我认为这是性能问题的原因。我将CreateObjectContext功能复制到我自己的项目中以提供此功能,如下所示:

代码语言:javascript
复制
    public static T CreateObjectContext<T>(DbConnection connection) where T : System.Data.Objects.ObjectContext {
        var workspace = new System.Data.Metadata.Edm.MetadataWorkspace(
          GetMetadataPathsString().Split('|'),
          // ^-- returns 
          //  "res://*/Redacted.csdl|res://*/Redacted.ssdl|res://*/Redacted.msl"
          new Assembly[] { typeof(T).Assembly });

        // The remainder of the method is copied straight from the original,
        // and I carried over a duplicate CtorCache too to make this work.
        var factory = DbProviderServices.GetProviderFactory(connection);
        var itemCollection = workspace.GetItemCollection(System.Data.Metadata.Edm.DataSpace.SSpace);
        itemCollection.GetType().GetField("_providerFactory", // <==== big fat ugly hack
            BindingFlags.NonPublic | BindingFlags.Instance).SetValue(itemCollection, factory);
        var ec = new System.Data.EntityClient.EntityConnection(workspace, connection);
        return CtorCache<T, System.Data.EntityClient.EntityConnection>.Ctor(ec);
    }

...but这似乎没有太大的不同。无论我是使用上面的黑客版本,还是mvc-mini-profiler提供的版本,问题都仍然存在。我想我应该提一下我也试过了。

在用尽所有这些之后,我已经无计可施了。再说一次:当我像往常一样提供数据上下文时,不会损失任何性能。当我提供一个“可分析的”数据上下文时,某些查询的性能会直线下降(我也不知道是什么影响了这一点)。mvc-mini-profiler会做什么错误的事情?我还在向它提供错误的数据吗?

我认为这和this person遇到的问题是一样的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-07-25 18:36:28

我今天刚刚解决了这个问题。

请参阅:http://code.google.com/p/mvc-mini-profiler/issues/detail?id=43

它的发生是因为我们的一些花哨的hack缓存得不够好。特别是:

代码语言:javascript
复制
var workspace = new System.Data.Metadata.Edm.MetadataWorkspace(
     new string[] { "res://*/" },       
     new Assembly[] { typeof(T).Assembly });

是一个非常昂贵的调用,所以我们需要缓存工作区。

票数 5
EN

Stack Overflow用户

发布于 2011-06-28 01:15:50

性能分析,by definition,将影响被分析的应用程序的性能。分析器需要在整个应用程序中插入它自己的方法调用,拦截低级系统调用,并将所有数据记录在某个位置(即写入磁盘)。所有这些任务都占用宝贵的CPU周期、内存和磁盘访问。

票数 -2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6454002

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档