对某些数据执行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秒。
发布于 2019-06-17 07:46:48
就您的代码而言,它似乎是获得所需内容的最佳方法(假设Includeing "demo3"两次是这个示例的一个错误)。
但是,您使用的数据库将有一种优化查询或底层数据结构的方法。使用数据库提供程序所需的任何工具来获取查询的执行计划,并查看它在哪里花费了这么多时间。你可能少了一两个索引。
发布于 2019-06-17 08:46:45
我建议延迟加载或加入查询。
可能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() func。懒惰的装载会解决你的问题。
其他的,您可以使用联接查询编写,
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 ... { };这两种解决方案解决了你所有的问题。如果它继续你的问题,我强烈建议存储程序。
发布于 2019-07-25 13:15:02
对于一个具有15+ "Include“语句并在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将在内存中执行筛选,这是一个非常耗时的过程。实体框架将修复内存中的任何关联。
https://stackoverflow.com/questions/56626822
复制相似问题