linq查询大约需要20秒才能对某些数据执行。将linq转换为sql时,有3个嵌套的联接可能需要花费更多的时间来执行。我们可以优化以下查询吗?
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秒。
答案 0 :(得分:0)
就您的代码而言,这似乎是获得所需内容的最佳方法(假设两次Include
和"demo3"
是本示例的错字。)
但是,您使用的数据库将有一种优化查询或基础数据结构的方法。使用数据库提供者必须使用的任何工具来获取查询的执行计划,并查看花费了很多时间的地方。您可能缺少一两个索引。
答案 1 :(得分:0)
我建议延迟加载或加入查询。
此查询可能是SQL输出;
(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()函数。延迟加载将解决您的问题。
其他情况下,您可以使用联接查询来编写
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 ... { };
这两个解决方案可以解决您的所有问题。 如果问题仍然存在,我强烈建议您执行存储过程。
答案 2 :(得分:0)
对于包含15个以上“包含”语句并在7分钟内生成2M +行的结果的查询,我遇到了类似的问题。
最适合我的解决方案是:
可以在下面找到一个示例:
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将在内存中执行过滤,这是一个非常耗时的过程。实体框架将修复内存中的所有关联。