C# 使用Distinct和Order By时,实体框架中存在多个查询,性能较差
EF EFCore v2.2.1中的以下LINQ查询C# 使用Distinct和Order By时,实体框架中存在多个查询,性能较差,c#,sql-server,entity-framework,C#,Sql Server,Entity Framework,EF EFCore v2.2.1中的以下LINQ查询 var x = context.Exchange .Include(q => q.Input) .Where(q => q.InputId != 1&& q.Input.CreatedOnUtc > DateTime.Parse("2019-11-25") && q.
var x = context.Exchange
.Include(q => q.Input)
.Where(q => q.InputId != 1&&
q.Input.CreatedOnUtc > DateTime.Parse("2019-11-25") &&
q.Input.UserId == 2 &&
q.BotConversationId == 3)
.Distinct()
.OrderBy(q => q.Input.CreatedOnUtc)
.FirstOrDefault()
最终简化了分析的SQL结果
select * from (
select distinct e.*
from Exchange e, ExchangeInput i
where e.InputId = i.InputId
and e.InputId <> 1
and i.UserId = 2
and e.BotConversationId = 3
)
为什么它需要执行两个单独的查询?当ExchangeInput可能有数百万行时,第二个查询非常可怕。
当然,这就足够了:
select * from (
select distinct e.*, i.CreatedOnUtc
from Exchange e, ExchangeInput i
where e.InputId = i.InputId
and e.InputId <> 1
and i.UserId = 2
and e.BotConversationId = 3
) a
order by a.CreatedOnUtc
另外,如我所料,将Distinct放在orderby之后只会给出1个查询
解决这个问题很容易。正在添加。选择。。。在.Distinct之前或删除.Distinct将执行此操作。但是,最初的、性能差的代码在查看时似乎不会立即出现问题 首先,我建议在FirstOrDefault之前调用Distinct是不必要的。当您有OrderBy时,非独立查询中的第一行应始终与独立查询相同!正如您在上一句中提到的,删除Distinct似乎只会创建一个查询 除了你的问题,我还建议在查询之外计算DateTime.Parse2019-11-25。这将允许您将其作为参数传递给数据库服务器,这可能会使您的查询更加高效 总之,我会尝试:
var dateFilter = DateTime.Parse("2019-11-25");
var x = context.Exchange
.Include(q => q.Input)
.Where(q => q.InputId != 1 &&
q.Input.CreatedOnUtc > dateFilter &&
q.Input.UserId == 2 &&
q.BotConversationId == 3)
.OrderBy(q => q.Input.CreatedOnUtc)
.FirstOrDefault()
您是对的,不需要使用distinct。我的主要问题是试图理解为什么这种语句会导致如此糟糕的性能,而从LINQ到SQL的转换似乎很简单。
var dateFilter = DateTime.Parse("2019-11-25");
var x = context.Exchange
.Include(q => q.Input)
.Where(q => q.InputId != 1 &&
q.Input.CreatedOnUtc > dateFilter &&
q.Input.UserId == 2 &&
q.BotConversationId == 3)
.OrderBy(q => q.Input.CreatedOnUtc)
.FirstOrDefault()