提高慢查询的性能 - 可能通过禁用更改跟踪

时间:2013-03-30 03:42:46

标签: c# performance entity-framework change-tracking entity-framework-6

我在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)

1 个答案:

答案 0 :(得分:1)

好吧,看起来你正在加载一个实体对象然后查询导航属性。发生这种情况时,EF会加载所有相关实体 FIRST (通过延迟加载),然后对整个集合执行查询。这可能就是您遇到性能问题的原因。

尝试使用以下方法查询集合:

context.Entry(targetBundle)
    .Collection(p => p.TradesReportEntries)
    .Query()
    .Where( e => <your filter here> )
    .Select( <your projection here> )

这允许您指定除幕后过滤器之外的过滤器,该过滤器默认处理加载nav属性。让我们知道它是如何运作的。