我想做一个左外连接来获取一些数据。但是,尽管在有用的列上创建了一些索引,但使用Entity Framework和C#LINQ join时,我的性能确实很差。我尝试了另一种使用多个连续FROM和WHERE子句的方法,并且看到了性能的巨大提升。
我想知道为什么SQL Server不选择更快的连接类型?我的LINQ查询连接是否有问题,导致性能如此糟糕?
这里的第一个版本超过3秒:
from calendarEvent in calendarEvents
join participants in ctx.CalendarEventParticipants on calendarEvent.Id equals participants.CalendarEventId into calendarEventWithParticipants
from subCalendarEventWithParticipant in calendarEventWithParticipants.DefaultIfEmpty()
select new { calendarEvent , subCalendarEventWithParticipant };
和需要200ms的版本:
from calendarEvent in calendarEvents
from participants in ctx.CalendarEventParticipants.Where(cep => cep.CalendarEventId == calendarEvent.Id).DefaultIfEmpty()
select new { calendarEvent , participants };
我在CalendarEventParticipants.calendarEventId
上有一个有用的索引。
我主要担心的是,使用连接的查询在理论上应该比具有where的第二个查询快得多。使用SSMS,我可以看到在执行NESTED LOOPS(左外连接)之前查询没有加入,这使我在这个查询上花了这么多钱。
谢谢
首先你的查询不清楚。您将CalendarEventId与calendarEvent.Id进行比较的方式
from calendarEvent in calendarEvents
from participants in ctx.CalendarEventParticipants.Where(cep => cep.CalendarEventId == calendarEvent.Id).DefaultIfEmpty()
select new { calendarEvents, participants };
其次,上面的查询看起来像一个嵌套查询,它始终是一个表演者。另一个花费较少时间的查询是使用join,它为您提供了联合目标集。性能取决于索引,大小和其他因素。但是如果表很大,那么嵌套查询不是正确的选择。而是使用连接。
from calendarEvent in calendarEvents
join participants in ctx.CalendarEventParticipants on calendarEvent.Id equals participants.CalendarEventId into calendarEventWithParticipants
from subCalendarEventWithParticipant in calendarEventWithParticipants.DefaultIfEmpty()
select new { calendarEvents, subCalendarEventWithParticipant };