【问题标题】:Improving performance of slow query - Potentially by disabling change tracking提高慢查询的性能 - 可能通过禁用更改跟踪
【发布时间】:2013-03-30 03:42:46
【问题描述】:

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

【问题讨论】:

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


    【解决方案1】:

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

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

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

    这允许您在默认情况下处理加载 nav 属性的幕后过滤器之外指定一个过滤器。让我们知道结果如何。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-03
      • 1970-01-01
      相关资源
      最近更新 更多