C# - 实体框架和SQL Server linq嵌套循环连接和散列连接性能

问题描述 投票:0回答:1

我想做一个左外连接来获取一些数据。但是,尽管在有用的列上创建了一些索引,但使用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(左外连接)之前查询没有加入,这使我在这个查询上花了这么多钱。

谢谢

sql-server performance linq
1个回答
0
投票

首先你的查询不清楚。您将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 };
© www.soinside.com 2019 - 2024. All rights reserved.