将 .ToArray() 放入 from/in [重复] 时,LINQ 查询性能不佳
Posted
技术标签:
【中文标题】将 .ToArray() 放入 from/in [重复] 时,LINQ 查询性能不佳【英文标题】:LINQ query has bad performance while putting .ToArray() inside from/in [duplicate] 【发布时间】:2021-01-11 16:21:27 【问题描述】:// the following approach takes sooooooo long
var result = (
from t in (
from a in ctx.t1
from b in ctx.t2
where a.id == b.id
select new a, b
).ToArray()
from c in ctx.t3.ToArray()
where c.name.Contains(t.a.name)
select new t.a, t.b, c
).ToArray();
// while the following approach takes time in seconds
var tSet = (
from a in ctx.t1
from b in ctx.t2
where a.id == b.id
select new a, b
).ToArray();
var cSet = ctx.t3.ToArray();
var result = (
from t in tSet
from c in cSet
where c.name.Contains(t.a.name)
select new t.a, t.b, c
).ToArray();
请考虑上面的代码。 FMPOV,这两种方法与数据集 (t1
& t2
) 和 t3
相同,这两种方法都将在 caluse 应用于它们的“第二”之前进行评估。
但是,实际情况是第一种方法比第二种方法花费的时间要长得多。我可以知道为什么吗?
提前致谢。
【问题讨论】:
那是因为第一个被翻译成类似tSet.SelectMany(t => ctx.t3.ToArray().Select(...))
的东西所以它在t3
表上为您从第一个查询获得的t1
表中的每一行执行ToArray
意味着不仅仅是两个 SQL 查询。对ToArray
或ToList
进行中间调用通常是个坏主意。
为什么将ToArray
放在 LINQ 查询中?
@juharr 谢谢。这应该是正确的答案。
【参考方案1】:
当您枚举数据(调用 ToArray、ToList 等)时,必须首先从数据库中获取该数据。将这些以及其他未在数据库中实现的枚举方法(作为本机操作或存储过程)视为数据库事务的结束。
您应该推迟枚举数据,直到绝对必要为止。
【讨论】:
以上是关于将 .ToArray() 放入 from/in [重复] 时,LINQ 查询性能不佳的主要内容,如果未能解决你的问题,请参考以下文章
List的toArray()方法和toArray(T[] a)方法
IN_MOVE_TO 是不是直接跟随 inotify 中的 IN_MOVE_FROM?