我在DbSet上有一个Linq查询,该查询命中一个表并获取65k行。查询大约需要3分钟,对我而言似乎显然太多了。虽然我没有比较线,但我确信这可以改进。我是EF和Linq的新手,所以我怀疑我也可能以一种很大的“不”的方式构建我的查询。
我读到更改跟踪是EF花费大部分时间的时间,并且已在相关实体上启用,所以也许我应该关闭它(如果是,如何)?
以下是代码:
ReportTarget reportTarget = repository.GetById(reportTargetId);
if (reportTarget != null)
{
ReportsBundle targetBundle = reportTarget.SavedReportsBundles.SingleOrDefault(rb => rb.ReportsBundleId == target.ReportsBundleId);
if (targetBundle != null)
{
}
}
下一行需要3分钟才能执行(65k记录):
IPoint[] pointsData = targetBundle.ReportEntries
.Where(e => ... a few conditions )
.Select((entry, i) => new
{
rowID = entry.EntryId,
x = entry.Profit,
y = i,
weight = target.HiddenPoints.Contains(entry.EntryId) ? 0 : 1,
group = 0
}.ActLike<IPoint>())
.ToArray();
注意: ActLike()来自Impromptu Interface库,它使用.NET DLR生成动态代理,实现动态接口。我怀疑这是瓶颈。
如何优化此特定DbSet(TradesReportEntries
)的性能,因为我将经常查询此表以获取大型数据集(IPoint[]
s)
答案 0 :(得分:1)
好吧,看起来你正在加载一个实体对象然后查询导航属性。发生这种情况时,EF会加载所有相关实体 FIRST (通过延迟加载),然后对整个集合执行查询。这可能就是您遇到性能问题的原因。
尝试使用以下方法查询集合:
context.Entry(targetBundle)
.Collection(p => p.TradesReportEntries)
.Query()
.Where( e => <your filter here> )
.Select( <your projection here> )
这允许您指定除幕后过滤器之外的过滤器,该过滤器默认处理加载nav属性。让我们知道它是如何运作的。