【问题标题】:Linq group by performanceLinq 按性能分组
【发布时间】:2023-01-31 06:30:35
【问题描述】:

我有一个帖子对象列表。每个帖子对象都有一个汽车属性,每个汽车对象都有一个品牌属性。我正在尝试查找特定品牌的帖子总数,为此我使用以下代码

var grp = posts.Where(t=> !t.Car.Brand.Name.Equals("Test"))
                .Select(t=> new Brand
                {
                    BrandId = t.Car.Brand.Id,
                    Name = t.Car.Brand.Name,
                    Url = t.Car.Brand.Url,
                })
                .GroupBy(t => t.BrandId)
                .Select(t=> new Brand
                {
                    BrandId = t.First().BrandId,
                    Name = t.First().Name,
                    Url = t.First().Url,
                    Count = t.Count()
                }).OrderByDescending(t=>t.Count).ToList();

这段代码有效,但有点慢,有什么提高性能的建议吗?

【问题讨论】:

  • 您可以发布生成的 SQL 吗?您也可以尝试致电BrandId = t.BrandId; Name = t.Max(s => s.Name); Url = t.Max(s => s.Url) 看看是否有帮助吗? t.First() 可能会做一些记忆中的事情,但我不确定。同时发布您的 ef 核心版本,您认为“慢”是什么?
  • 也许分两步完成。执行 .ToList() 然后分组:.GroupBy(t => t.BrandId).Where(w => w.Count() > 1)。

标签: c# linq


【解决方案1】:

在分组结果上使用 First() 会显着降低性能。在 EF Core 6 之前,它将排除此查询不可翻译的异常。如果您想编写高性能查询,请始终以 SQL 方式思考:分组只能返回分组键和聚合结果,其他怪癖很慢,即使它们可以转换为 SQL。

var grp = posts
    .Where(t => !t.Car.Brand.Name.Equals("Test"))
    .Select(t=> new Brand
    {
        BrandId = t.Car.Brand.Id,
        Name = t.Car.Brand.Name,
        Url = t.Car.Brand.Url,
    })
    .GroupBy(t => t)
    .Select(t=> new Brand
    {
        BrandId = t.Key.BrandId,
        Name = t.Key.Name,
        Url = t.Key.Url,
        Count = t.Count()
    })
    .OrderByDescending(t => t.Count)
    .ToList();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-17
    • 2012-11-16
    • 2017-11-17
    • 1970-01-01
    • 2012-05-17
    相关资源
    最近更新 更多