加快实体框架

时间:2014-06-15 08:29:43

标签: c# entity-framework asp.net-mvc-4

我一直在寻找优化使用MVC 2和EF4的Web应用程序。

表示列表查询大约需要22个行,大约10k行,包含14列,这显然太慢了。

因此,作为其中的一部分,我已升级到MVC 4和EF 6.1(我可以使用VS2010获得最高分)。

对于只读查询,我在查询中添加了.AsNoTracking(),这将时间减少到~3秒。我想知道是否还有其他任何事情可以让它降低到〜1秒。

到目前为止,我的代码是:

category = CategoryHelper.MapToOldFormat(category);
var mainIds = Repository.Categories
               .Include(o => o.LinkedCategories)
               .Where(o => o.Category1.Contains(category))
               .AsNoTracking()
               .ToList();
var linkedCats = mainIds.SelectMany(o => o.LinkedCategories).Union(mainIds).Select(c => c.Id);

var notifications = Repository.Notifications
                .Include(o => o.Country)
                .Include(o => o.NonEUCountries)
                .Include(o => o.Language)
                .Include(o => o.RAW)
                .Include(o => o.RAW.Classification)
                .Include(o => o.RAW.TransactionPN)
                .AsNoTracking();

if (id != null)
{
    notifications = notifications.Where(o => o.Id == id);
}

if (!string.IsNullOrWhiteSpace(category))
{
    notifications = notifications.Where(o => linkedCats.Contains(o.RAW.Classification.CategoryID));
}

return notifications.Logged(MethodBase.GetCurrentMethod()).ToList();

在基准测试类别中,wand id为null,因此不会生成类别的IN。我将在未来用intflag替换它作为支持多个类别的快速方法。

此示例查询是否还有其他重大性能问题?

1 个答案:

答案 0 :(得分:3)

首先,列出10k的结果很痛苦。您需要对大型数据集使用分页。

想象一下将关系数据移动到某些类的10k实例并注入运行时功能(如自我跟踪或延迟加载)的成本。一个10k迭代循环,每次迭代都有复杂的代码。它默认应该很慢,不应该吗?

因此,您似乎需要利用LINQ的扩展方法like .Skip(...) and .Take(...).

另一项改进是分析您的数据库和对象模型中的当前数据模式的结果,因为 1表是1类(具有14列/属性)可能是一个问题:也许是分段设计可以改善您的方案。

无论如何,分页将是你的朋友。这应该将查询时间缩短到几分之一秒。

更新

@Phyx在评论中说:

  

我继承了该项目并且没有预算来更改所有项目   目录。

如果你无法改变,I would say caching should be the solution。 1个用户应该接收这些未经优化(不可优化的)查询的影响,其余的将使用可能持续较小时间间隔的输出缓存,但它可能足以加速您的应用程序并减少加载时间。