简体   繁体   English

LINQ选择里面有很多ToList花费太多时间

[英]LINQ select with many ToList inside takes too much time

I've below select with LINQ query that takes too much time If I do ToList inside Select on AsQueryable . 我在下面使用LINQ查询进行select ,如果我在Select on AsQueryable执行ToList ,则会花费太多时间。

Approch 1 方法1

Takes approx 10s 大约需要10秒

This is simplest representation of my data with different ToList() 这是使用不同的ToList()来最简单地表示我的数据

Below MYTABLE has one to many relationship with COLUMN (another table) which has Description field MYTABLE以下与COLUMN (另一个表)具有一对多关系,其中COLUMN具有Description字段

using profiler query has UNION ALL for all ToList but query itself execute within 100ms, seems like it takes to parse by C# 使用探查器查询对所有ToList都具有UNION ALL,但查询本身在100毫秒内执行,似乎需要C#进行解析

  // Project into usable data and enumerate
            var enumerated = await this.Context.MYTABLE.AsQueryable().Where(some condition).Select(x => new
            {
                Study1 = x.COLUMN.Select(j => j.Description1).ToList(),
                Study2 = x.COLUMN.Select(j => j.Description2).ToList(),
                Study3 = x.COLUMN.Select(j => j.Description3).ToList(),
                Study4 = x.COLUMN.Select(j => j.Description4).ToList(),
                Study5 = x.COLUMN.Select(j => j.Description5).ToList()
            }).ToListAsync(cancellationToken);

            var results = enumerated.Select(o => new
            {
                Result1 = string.Join(", ", o.Study1),
                Result2 = string.Join(", ", o.Study2),
                Result3 = string.Join(", ", o.Study3),
                Result4 = string.Join(", ", o.Study4),
                Result5 = string.Join(", ", o.Study5),
            }).ToList();

            return results;

Approch 2 方法2

Takes approx 2s 大约需要2秒

using profiler query is very small compare to previous, around 1/5 lines 与以前的相比,使用探查器查询的规模很小,大约为1/5行

// Project into usable data and enumerate
        var enumerated = await this.Context.MYTABLE.AsQueryable().Where(some condition).Select(x => new
        {
            x.COLUMN
        }).ToListAsync(cancellationToken);

        var results = enumerated.Select(o => new
        {
            Result1 = string.Join(", ", o.COLUMN.Select(j => j.Description1).ToList()),
            Result2 = string.Join(", ", o.COLUMN.Select(j => j.Description2).ToList()),
            Result3 = string.Join(", ", o.COLUMN.Select(j => j.Description3).ToList()),
            Result4 = string.Join(", ", o.COLUMN.Select(j => j.Description4).ToList()),
            Result5 = string.Join(", ", o.COLUMN.Select(j => j.Description5).ToList()),
        }).ToList();

        return results;

Why Approch 2 takes less time and query is also simpler then 1? 为什么Approch 2需要更少的时间,而查询也比1更简单?

Is there any suggestion to improve LINQ performance 有什么建议可以提高LINQ性能

Edit 编辑

I notice in Approch 2 it will call database multiple times for subsequent ToList() but still with all those calculation, Database retrieves within few milliseconds while C# take much more time. 我注意到在方法2中 ,它将为后续的ToList()多次调用database ,但是仍然进行所有这些计算, Database在几毫秒内检索到,而C#需要更多时间。

Approch 3 方法3

This is also take around 2s . 这也需要2s左右的时间。

I just did ToList first in Approch 1. 我只是在方法1中首先进行了ToList

 // Project into usable data and enumerate
  var enumerated2 =  await this.Context.MYTABLE.AsQueryable().Where(some condition).ToListAsync(cancellationToken);

            var enumerated = enumerated2.Select(x => new
            {
                Study1 = x.COLUMN.Select(j => j.Description1).ToList(),
                Study2 = x.COLUMN.Select(j => j.Description2).ToList(),
                Study3 = x.COLUMN.Select(j => j.Description3).ToList(),
                Study4 = x.COLUMN.Select(j => j.Description4).ToList(),
                Study5 = x.COLUMN.Select(j => j.Description5).ToList()
            }).ToList()

            var results = enumerated.Select(o => new
            {
                Result1 = string.Join(", ", o.Study1),
                Result2 = string.Join(", ", o.Study2),
                Result3 = string.Join(", ", o.Study3),
                Result4 = string.Join(", ", o.Study4),
                Result5 = string.Join(", ", o.Study5),
            }).ToList();

            return results;

I don't understand why Approch 3 took less time then Approch 1 where only difference is performing ToList method. 我不明白为什么Approch 3花费的时间少于Approch 1所执行的ToList方法的时间。

  1. Why do you need to call .ToList() twice? 为什么需要两次调用.ToList() Remove the first one, that will help a bit. 删除第一个,这会有所帮助。
  2. Try using .Include("Tablename") . 尝试使用.Include("Tablename") You can read about it here: https://medium.com/@lucavgobbi/improving-performance-with-linq-b478cd77d105 您可以在这里阅读有关内容: https : //medium.com/@lucavgobbi/improving-performance-with-linq-b478cd77d105

This is probably the so-called "n+1 problem" you are facing. 这可能是您面临的所谓“ n + 1问题”。 You can read about it here: https://www.brentozar.com/archive/2018/07/common-entity-framework-problems-n-1/ 您可以在这里阅读有关内容: https : //www.brentozar.com/archive/2018/07/common-entity-framework-problems-n-1/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM