groupby 内部 groupby 和 All() 性能

Groupby inside groupby and All() performance

我有一个将数据分组两次的查询:

var query = (from a in Context.SetA()
from b in Context.SetB().Where(x => x.aId == a.Id) // 1-to-many
from c in Context.SetC().Where(x => x.bId == b.Id) // 1-to-many
group new {...} by new {...} into g
select new
{
    g.Key.X,
    g.Key.Y,
    g.Sum(x => x....), // etc, lots of Sums
});

from (q in query
group q by true
select new 
{
    g.Key.Z,
    g.Sum(x => x.....), // etc, lots of Sums
});

一切正常,性能可以接受。现在,当我在两个分组中添加全部(或任何,没有区别)时

g.All(x => x.Flag)

性能急剧下降。它变得慢了 10 倍,从 5 秒到 50 秒。数字不准确,只是为了得到这个想法。

我进行了两次分组,因为我有三个级别的一对多关系,并且我在所有级别上进行汇总(父值之和、子值之和和孙值之和)。

有什么想法可以提高性能吗?

问题是没有自然的 SQL GROUP BY 聚合可以映射到 All / Any 应用于分组,所以 EF SQL 翻译效率低下。

解决方案是使用它们的聚合等价物。

所以不用

g.All(x => x.Flag)

你可以使用

g.Min(x => x.Flag ? 1 : 0) == 1

分别

g.Any(x => x.Flag)

可以替换为

g.Max(x => x.Flag ? 1 : 0) == 1

更新: 奇怪的是,EF 生成 2 个 MIN / MAX 调用上述表达式。这是通过在末尾(== 1 之后)添加违反直觉的 ? true : false

来解决的