首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用多个包含语句优化linq查询

使用多个包含语句优化linq查询
EN

Stack Overflow用户
提问于 2019-06-17 07:43:01
回答 3查看 1.3K关注 0票数 0

对某些数据执行linq查询大约需要20秒。当将linq转换为sql时,有3个嵌套联接可能需要更多时间执行。我们能优化以下查询吗?

代码语言:javascript
复制
var query = (from s in this.Items 
             where demoIds.Contains(s.Id)      
             select)
             .Include("demo1")
             .Include("demo2")
             .Include("demo3")
             .Include("demo4");

return query;

我们的期望是在3-4秒内执行该查询,现在在100 demoIds中大约需要20秒。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-06-17 07:46:48

就您的代码而言,它似乎是获得所需内容的最佳方法(假设Includeing "demo3"两次是这个示例的一个错误)。

但是,您使用的数据库将有一种优化查询或底层数据结构的方法。使用数据库提供程序所需的任何工具来获取查询的执行计划,并查看它在哪里花费了这么多时间。你可能少了一两个索引。

票数 0
EN

Stack Overflow用户

发布于 2019-06-17 08:46:45

我建议延迟加载或加入查询。

可能SQL输出就是这个查询;

代码语言:javascript
复制
(SELECT .. FROM table1 WHERE ID in (...)) AS T1
   (INNER, FULL) JOIN (SELECT .. FROM table2) AS T2 ON T1.PK = T2.FOREIGNKEY
   (INNER, FULL) JOIN (SELECT .. FROM table3) AS T3 ON T1.PK = T3.FOREIGNKEY
   (INNER, FULL) JOIN (SELECT .. FROM table4) AS T4 ON T1.PK = T4.FOREIGNKEY

但是,如果可以使用延迟加载,则不需要使用Include() func。懒惰的装载会解决你的问题。

其他的,您可以使用联接查询编写,

代码语言:javascript
复制
var query = from i in this.Items.Where(w=>demoIds.Contains(w.Id))
            join d1 in demo1 on i.Id equals d1.FK
            join d2 in demo2 on i.Id equals d2.FK
            join d3 in demo3 on i.Id equals d3.FK
            select new ... { };

这两种解决方案解决了你所有的问题。如果它继续你的问题,我强烈建议存储程序。

票数 0
EN

Stack Overflow用户

发布于 2019-07-25 13:15:02

对于一个具有15+ "Include“语句并在7分钟内生成2M+行结果的查询,我遇到了类似的问题。

对我有效的解决办法是:

  1. 禁用延迟加载
  2. 禁用自动检测更改
  3. 将大查询拆分为小块

以下是一个样本:

代码语言:javascript
复制
public IQueryable<CustomObject> PerformQuery(int id) 
{
 ctx.Configuration.LazyLoadingEnabled = false;
 ctx.Configuration.AutoDetectChangesEnabled = false;

 IQueryable<CustomObject> customObjectQueryable = ctx.CustomObjects.Where(x => x.Id == id);

 var selectQuery = customObjectQueryable.Select(x => x.YourObject)
                                                  .Include(c => c.YourFirstCollection)
                                                  .Include(c => c.YourFirstCollection.OtherCollection)
                                                  .Include(c => c.YourSecondCollection);

 var otherObjects = customObjectQueryable.SelectMany(x => x.OtherObjects);

 selectQuery.FirstOrDefault();
 otherObjects.ToList();

 return customObjectQueryable;
 }

为了在服务器端进行所有的过滤,需要使用IQueryable。IEnumerable将在内存中执行筛选,这是一个非常耗时的过程。实体框架将修复内存中的任何关联。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56626822

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档