我想优化以下 LINQ 语句的性能,或者需要一些可以更有效地执行的替代方案......
var temp = (from r in jc
group r by new { r.City, r.Gender, r.AgeBracket } into g
select new Summary
{
Population = g.Sum(x => (decimal)x.Population),
State = g.Select(x => x.City).First(),
Gender = g.Select(x => x.Gender).First(),
AgeBracket = g.Select(x => x.AgeBracket).First()
}).ToArray();
请让我知道 LINQ 执行此类操作的任何替代方法,因为我观察到 LINQ 在生成大量数据的结果方面具有相当大的性能开销。
编辑-1我不是从数据库中查询它,但我有用于生成摘要的内存对象的自定义。
您可以使用g.Key.XXX
代替g.Select(xxx).First
:
select new Summary
{
Population = g.Sum(x => (decimal)x.Population),
State = g.Key.City,
Gender = g.Key.Gender,
AgeBracket = g.Key.AgeBracket
}
首先,LINQ 与性能无关,而与便利性有关。要了解它的性能,您需要进行剖析。首先要做的是找出:
- 它正在生成什么 TSQL
- 它返回了多少行
- 在数据库中执行需要多长时间
- 在客户端执行需要多长时间
如果 TSQL 看起来不错,并且两个计时大致相同,那么您可能需要添加索引。如果 TSQL 很糟糕和/或在数据库中运行的时间太长,那么您可能需要手动滚动 TSQL。如果数据库时间很好,但在 .NET 中执行需要花费大量时间,那么这可能是映射器故障(有时会发生) - 考虑像 dapper 这样的工具。如果只是行数:想想一个新的设计;也许是分页。
优化没有一个答案。首先,您需要确定瓶颈。
用老式的方式做:)按城市、性别、年龄jc
排序。循环访问排序结果总和总体。当城市、性别、年龄发生变化时,输出一个包含前一个城市、性别、年龄和总和的摘要。将总和重置为零并继续。