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
来解决的
我有一个将数据分组两次的查询:
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