我一直在寻找优化使用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替换它作为支持多个类别的快速方法。
此示例查询是否还有其他重大性能问题?
答案 0 :(得分:3)
首先,列出10k的结果很痛苦。您需要对大型数据集使用分页。
想象一下将关系数据移动到某些类的10k实例并注入运行时功能(如自我跟踪或延迟加载)的成本。一个10k迭代循环,每次迭代都有复杂的代码。它默认应该很慢,不应该吗?
因此,您似乎需要利用LINQ的扩展方法like .Skip(...)
and .Take(...)
.
另一项改进是分析您的数据库和对象模型中的当前数据模式的结果,因为 1表是1类(具有14列/属性)可能是一个问题:也许是分段设计可以改善您的方案。
无论如何,分页将是你的朋友。这应该将查询时间缩短到几分之一秒。
@Phyx在评论中说:
我继承了该项目并且没有预算来更改所有项目 目录。
如果你无法改变,I would say caching should be the solution。 1个用户应该接收这些未经优化(不可优化的)查询的影响,其余的将使用可能持续较小时间间隔的输出缓存,但它可能足以加速您的应用程序并减少加载时间。