C# 将IEnumerable与IQueryable联接时的LINQ性能问题

C# 将IEnumerable与IQueryable联接时的LINQ性能问题,c#,.net,performance,linq,C#,.net,Performance,Linq,在这段代码中,我对LINQ有一些严重的速度问题(变量名已更改) 即使B表和C表中的行数少于100k,此LINQ也需要10秒以上的时间来执行 我对此进行了研究,通过反复试验,我将代码更改为: var A = _service.GetA(param1, param2).Where(a => a.boolVariable); // Returns Enumerable results var results = (from b in _B.All() // _B.All() returns I

在这段代码中,我对LINQ有一些严重的速度问题(变量名已更改)

即使B表和C表中的行数少于100k,此LINQ也需要10秒以上的时间来执行

我对此进行了研究,通过反复试验,我将代码更改为:

var A = _service.GetA(param1, param2).Where(a => a.boolVariable); // Returns Enumerable results

var results = (from b in _B.All() // _B.All() returns IQueryable
        join c in _C.All() on b.Id equals c.Id // _C.All() returns IQueryable
        join a in A on a.Id equals c.Id
        where b.someId == id
        select new
        {
          ...
        }).ToList();

所以我的问题是,为什么这个简单的更改会对LINQ性能产生如此剧烈的影响?唯一的变化是我预先过滤了可枚举列表,可枚举列表在过滤前有30个项目,过滤后有15个项目。

在第一个场景中:首先它将所有记录合并到一个需要很长时间才能合并的列表中,然后过滤掉
A.boolVariable


在第二个场景中,您在加入之前有一个较小的a记录子集-当然,这将花费较少的时间加入。

即使您有10个记录与5个记录,这将意味着这些B&C中所有其他100K记录的10倍与5倍100K。更不用说以后所有这些记录都需要过滤掉(过滤10条记录vs 10000条记录)。@Dadoss因此,基本上,当您将IQueryable和IEnumerable混合使用时,将在sql server上执行和不执行的内容上会出现一条灰线。现在,通过在where子句中使用IENumerable(第一种情况),它将强制部分查询进入内存。但在第二种情况下,实体框架将通过将最后一个连接加入虚拟select或完全将其去掉并将其添加为where(in),使sql稍微好一点。所有这些都只是我多年来尝试的各种linq查询的推测。当您对原始代码运行SQL跟踪时,提交给数据库的是什么?当您为最终代码运行SQL跟踪时,提交到数据库的是什么?我猜
a.boolVariable
b.someId==id
的顺序可能会颠倒或改变。请更新您的问题,以准确显示在这两种情况下提交到数据库的内容。我想你忘了编辑你的问题来包含它。请同时向我们展示
GetA
@Dadoss的源代码。如果你不愿意展示源代码,你的问题很可能会被关闭。至关重要的是,你要表现出良好的心态。许多提问的人认为某些事情是无关紧要的。他们经常是不正确的。这是至关重要的。当我们试图帮助你时,你把我们的手绑在背后。错误几乎可以肯定是因为该方法返回
IEnumerable
var A = _service.GetA(param1, param2).Where(a => a.boolVariable); // Returns Enumerable results

var results = (from b in _B.All() // _B.All() returns IQueryable
        join c in _C.All() on b.Id equals c.Id // _C.All() returns IQueryable
        join a in A on a.Id equals c.Id
        where b.someId == id
        select new
        {
          ...
        }).ToList();