繁体   English   中英

EF Core 查询非常慢,表之间有很多关系

[英]EF Core query is extremely slow with many relations between tables

我有一个这样的 EF Core 查询:

var existingViolations = await _context.Parent
       .Where(p => p.ProjectId == projectId)
          .Include(p => p.Relation1)
          .Include(p => p.Relation2)
               .ThenInclude(r => r.Relation21)
          .Include(p => p.Relation3)
        .AsSplitQuery()
        .ToListAsync();

此查询通常需要 55-65 秒,这有时会导致数据库超时。 查询中包含的所有表(包括父表)都包含 30k-60k 行和 3-6 列。 我尝试使用LoadAsync()将其拆分为较小的查询,如下所示:

_context.ChangeTracker.LazyLoadingEnabled = false;
_context.ChangeTracker.AutoDetectChangesEnabled = false;

await _context.Relation1.Where(r1 => r1.Parent.ProjectId == projectId).LoadAsync();

await _context.Relation2.Where(r2 => r2.Parent.ProjectId == projectId).Include(r2 => r2.Relation21).LoadAsync();

await _context.Relation3.Where(r3 => r3.Parent.ProjectId == projectId).LoadAsync();

var result = await _context.Parent.Where(p => p.ProjectId == projectId).ToListAsync();

这将查询时间缩短了大约 5 秒,所以没什么可吹嘘的。 我已经做了一些计时,这是迄今为止完成时间最长的最后一行( var result = await _context.Parent.Where(p => p.ProjectId == projectId).ToListAsync(); ),大约 90花费时间的百分比。

我该如何进一步优化呢?

在没有看到真实实体以及它们如何配置的情况下,这是任何人的猜测。

一般来说,在查看此类性能问题时,我首先要解决的是“加载这些数据的目的是什么?” 通常,当我看到使用大量Include的查询时,这类似于基于所选数据为视图或计算加载的读取操作。 如果您真的只需要每个表中的几列来满足您的需求,那么投影到更简单的 model 在这里会大有帮助。 在相关数据中使用Select进行投影以填充 DTO/ViewModel class 用于视图或匿名类型用于计算的好处是, Include将希望传递一个 Z34D1F91 中所有急切加载表的所有列,其中 FB12E514B98576A,投影只会传回引用的列。 当表可以包含您根本不需要或立即不需要的大型文本/二进制列之类的内容时,这可能非常重要。 这在数据库服务器可能与消费客户端或 web 服务器有一定距离的情况下也非常重要。 网络上的数据越少 = 性能越快,尽管现在的问题听起来像是数据库查询本身。

接下来要检查的是所有表和 EF 中的任何相关配置与表设计之间的关系。 等待一分钟从 30-60k 行中提取几条记录的时间太长了,我高度怀疑某些不使用 FK/索引的有缺陷的关系映射。 另一个值得关注的地方是对数据库运行分析器以捕获正在运行的确切 SQL 语句,然后手动执行这些语句以调查其执行计划,这可能会揭示架构问题或实体关系映射产生的一些怪异导致效率非常低查询。

接下来要检查的是使用消除过程来查看是否存在不良关系。 一个一个地消除每个急切的加载Include语句,看看每个查询场景需要多长时间。 如果有一个特定的Include导致急剧减速,请深入研究该关系以了解原因。

这应该给你几个途径来检查。 考虑使用实际实体和任何进一步的故障排除结果修改您的问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM