mvc-mini-profiler减慢了实体框架的速度

时间:2011-06-23 12:29:36

标签: entity-framework mvc-mini-profiler

我已经针对我的Entity Framework支持的MVC 3站点设置了mvc-mini-profiler。一切都是适当的配置;在Application_Start中开始分析,在Application_End中结束它,依此类推。分析部分工作得很好。

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

在查询,执行和“数据读取”SQL时可以忽略不计的时间(~2ms tops),而这一行:

var person = dataContext.People.FirstOrDefault(p => p.PersonID == id);

...包裹在using(profiler.Step())时记录为300-400毫秒。我用dotTrace进行了分析,确认时间实际上是照常用在EF中(可用的组件确实非常短暂地出现),只是需要更长的时间。

这让我相信连接或其某些组成部分缺少足够的数据,使EF表现更差。

这就是我用来创建上下文对象的东西(我的edmx模型的类叫做DataContext):

var conn = ProfiledDbConnection.Get(
    /* returns an SqlConnection */CreateConnection());
return CreateObjectContext<DataContext>(conn);

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

    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);
    }

......但它似乎并没有多大区别。无论我是否使用上面提到的特定于元数据工作空间路径的黑客版本或mvc-mini-profiler提供的版本,问题仍然存在。我只是想提到我也试过这个。

已经筋疲力尽了,我的斗智尽头。再一次:当我像往常一样提供我的数据上下文时,不会丢失任何性能。当我提供“profilable”数据上下文时,某些查询的性能会下降(我不知道是什么影响了这一点)。 mvc-mini-profiler有什么用呢?我还在给它提供错误的数据吗?

我认为这与this person遇到的问题相同。

2 个答案:

答案 0 :(得分:5)

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

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

这是因为我们的一些花哨的黑客没有得到足够的缓存。特别是:

var workspace = new System.Data.Metadata.Edm.MetadataWorkspace(
     new string[] { "res://*/" },       
     new Assembly[] { typeof(T).Assembly });

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

答案 1 :(得分:-2)

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