【问题标题】:Entity Framework Core, count of include too slow compared to T-SQLEntity Framework Core,与 T-SQL 相比,包含的计数太慢
【发布时间】:2019-06-20 00:42:23
【问题描述】:

编辑:在 ProductAttributes 上删除了其他包含仍然相同的结果表大小 50k 行

我得到了这段代码,与我的 T-SQL 语句相比,它的运行速度太慢了。

return _context.ProductAttributes
               .Include(e => e.ProductProductAttributes)
               .Select(x => new GetProductAttributesModel
                                {
                                    Attribute = x,
                                    Count = x.ProductProductAttributes.Count()
                                })
               .ToArrayAsync(); 

这是用于比较的 T-SQL 语句:

SELECT * 
FROM Product_Attribute a 
LEFT JOIN 
    (SELECT COUNT(*) AS ctn, AttributeId 
     FROM Product_ProductAttribute 
     GROUP BY AttributeId) d ON d.AttributeId = a.Id 

如何获得更快或至少类似于 T-SQL 语句的 Entity Framework Core 实现?

我希望我不需要为此在选择中执行存储过程...看起来很简单

【问题讨论】:

  • 查询计划显示/建议什么?可能根本与 LINQ/EF 无关。至少我看不出有什么问题。
  • Entity Framework 旨在提高程序员的生产力 - 它从来没有被设计成比原始 SQL 更快(而且它不可能 - 毕竟,它比简单的 T-SQL 语句做的工作要多得多)。
  • 你的 EF 代码总是比纯 sql 慢。这是预期的行为
  • 这两个查询完全不同。您的 SQL 版本中甚至没有使用“Relatives”表...
  • 您不需要任何 Inculde() 调用 - 没有它,您的查询可以在 SQL 端进行评估。

标签: c# entity-framework-core


【解决方案1】:

好的,社区一致认为实体不会为我提供此用例所需的速度。对于这种情况,我将切换到一个存储过程到一个选择中。

【讨论】:

  • 我必须问一下,您的应用程序功能是否完整且经过全面的功能测试?如果你有更大的鱼要炸,你为什么还要为性能而烦恼。
  • 不,这是一项新功能。这显示了使用属性来帮助用户删除未使用的属性。问题是计数很慢。如果存储过程太慢,我什至可以稍后缓存/批处理。
  • 我敢打赌,假设您的结果集不是很大,您可以通过一点努力从 EF 中获得类似的时间。您可以使用 DbContext.Database.Log 回调记录查询 - 也许尝试一下,看看 SQL EF 产生了什么。
  • 就这样开始了.. 当我体验到原始 sql 性能时,我的生活发生了变化。我建议你使用 dapper 和 nameof(DomainModel.Variable)/nameof(Database.Table) 来维护智能感知,否则你会在明年需要更改模型或查看引用时后悔
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-11-19
  • 2016-09-28
  • 2016-08-04
  • 2017-03-24
  • 2014-10-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多