【发布时间】:2020-01-11 21:54:42
【问题描述】:
我在select 下方使用LINQ 查询需要太多时间如果我在Select 内AsQueryable 上执行ToList。
接近 1
大约需要 10 秒
这是我使用不同 ToList() 的数据的最简单表示形式
MYTABLE 下方与COLUMN(another table) 具有一对多关系,Description 字段
使用分析器查询对所有 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;
方法 2
大约需要 2 秒
使用 profiler 查询与之前相比非常小,大约 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;
为什么 Approch 2 花费的时间更少,查询也比 1 更简单?
有什么建议可以提高LINQ 的性能
编辑
我注意到在 Approch 2 中,它会多次调用 database 以用于后续的 ToList(),但仍然通过所有这些计算,Database 在几毫秒内检索,而 C# 需要更多时间。
方法 3
这也是2s。
我刚刚在 Approch 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;
我不明白为什么Approch 3 比Approch 1 花费的时间更少,唯一的区别是执行ToList 方法。
【问题讨论】:
-
你为什么要在
StudyX上给.ToList()打两次电话?一次进入第一次选择,然后再次进入结果选择。 -
@John 问题已更新
-
实体框架?实体框架核心?
-
@Jota.Toledo 实体框架
标签: c# performance linq profiling