繁体   English   中英

实体框架两个查询具有相同的结果,但一个查询速度更快

[英]Entity Framework Two queries with same results, but one is faster

我最近在实体框架查询SQL Server 2008时遇到了性能问题。我设法解决了这个问题,但我不明白为什么我的修复工作正常。 我正在使用一个带有.Contains()方法的Guids集合来在SQL中生成一个IN子句。 这是原始代码(更改表名以保护无辜者):

Guid[] values = filter.Split(',').Select<String, Guid>(d => new Guid(d)).ToArray();


returnValue = returnValue.Where(t => values.Contains(t.WorkItem.Requirement.Project.ProjectId));

当有> 150个ProjectID时,此查询需要大约20秒才能执行。 通过改变.Contains()的位置,我可以大大加快速度。 这是重构:

Guid[] values = filter.FilterValue.Split(',').Select<String, Guid>(d => new Guid(d)).ToArray();

var projects = from p in context.DC_DEF_Project
               where values.Contains(p.ProjectId)
               select p;

returnValue = from t in returnValue
              join p in projects on t.DC_DEF_ProjectWorkItem.DC_DEF_ProjectRequirement.ProjectId equals p.ProjectId
              select t;

此代码在与上述查询相同的数据集上花费约0.125秒。

我确信这是一个理智的理由,但我的好奇心正在扼杀我。 它是什么?

我的猜测是,第一个导致sql带有一堆或ORs在工作项上的外键之后进行评估,其中第二个通过它的主键连接到项目的第一个并且只评估150个ID然后将其连接到其他表格。

我想在第一个例子中,您将整个数据集转移到您的应用程序,然后对其进行内存中的linq查询。

据我所知,Linq的工作必须与延迟执行查询有关。

在您的固定版本中,您有两个Linq表达式将一个接一个地进行求值和解释,但在枚举结果时执行一次如果有的话 )。 这巧妙地减少了数据库访问

第一个版本:

returnValue.Where(t => values.Contains(t.WorkItem.Requirement.Project.ProjectId))

在第一步中没有进行任何过滤。 它将检查当前表行的ProjectId是否包含在表的每一行values中!

暂无
暂无

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

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