C# LINQ SUM 花费的时间比预期更长

问题描述 投票:0回答:1

我目前正在测试 MVC 应用程序,发现其中一个页面似乎需要更长的时间。 通过逐行测量每次执行的时间,我发现其中一个 LINQ 行需要超过 5 秒的时间。我知道查询本身并不复杂,但数据库中只有数百或数千行。

grandTotal = items.Sum(x => x.InvoiceDetails.Sum(s => s.BillingItem.TotalAmount)) ?? 0;

无论如何,是否可以让这个操作执行得更快?我查了另一个线程,说通过 forloop 实际上比 LINQ 更快。但由于

item
是 IQueryable 的类型,我认为这是从我的知识中得出总和的唯一方法。

c# linq iqueryable
1个回答
0
投票

如果查询必须一次作为单个事务完成,那么这里使用 Sum 的一个糟糕实现是。 D Stanley 在对你的问题的评论中询问了这一点。理想情况下,如果数据库有 CPU 来处理,您希望计算在数据库中进行,因为这样可以最大限度地减少需要传输的数据量。否则,您需要执行一个查询来提取相关行,然后在本地对它们求和。

您可能发生的情况是这样的:

query first bill total value from server
add total to sum
query second bill total value from server
add total to sum
etc.

这些都是我们要避免的相对较慢的数据连接。所以,有 2 个解决方案:

  1. 将 InvoiceSum 存储过程添加到您可以调用的数据库中。我假设这不是一个选择,但如果是的话,对您来说可能是最快的。 (沿着这些思路,您还可以向数据库发送一个请求来进行求和,但这会失去通用 LINQ 语句的灵活性。)
  2. 将所有行收集为单个查询。您可能无法使用您正在使用的库来执行此操作。 LINQ,或多或少根据定义,使用 Enumerable,它一次只查看一个元素。

关于 for 循环与 LINQ 的注释。 LINQ 的开销比 for 循环稍多,但特别是对于较大的循环,差异很小。如果您要进行大量小查询,for 循环可能会更好,因为它不会增加垃圾收集器的压力。但偶尔使用 LINQ 语句会非常经济实惠。性能检查总是一个好主意,看看它是否确实存在问题。当然,只需删除嵌套的 Sum 语句并用 for 循环替换它,您可能会做得很好。

© www.soinside.com 2019 - 2024. All rights reserved.