【发布时间】:2018-08-31 11:04:58
【问题描述】:
我想做一个左外连接来获取一些数据。但是,尽管在有用的列上创建了一些索引,但使用 Entity Framework 和 C# LINQ 连接时我的性能确实很差。我尝试了另一种方法,将多个连续的 FROM 与 WHERE 子句一起使用,并看到了性能的巨大提升。
我想知道为什么 SQL Server 不选择更快的连接类型?我是否对我的 LINQ 查询连接做错了什么导致性能如此糟糕?
这里是第一个耗时超过 3s 的版本:
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(左外连接)之前没有 JOIN,这在此查询上花费了我很多。
谢谢
【问题讨论】:
-
请试着想象读者回答问题需要什么。您不知道生成了哪个 SQL,因此我们不知道您所说的“更快的连接类型”是什么意思。此外,了解您使用的 ORM(+ 版本!)也很重要。而且通常类定义和映射也是相关的,因为必需和非必需的关联在连接中表现不同。
-
什么是
hashjoin? -
@GertArnold:你好!这是 C# 代码,所以这里没有显示 SQL。我确实可以转储发送到 SQL SERVER 的查询,但这真的很难理解。我们使用实体框架。
-
@NetMage:你好!请参考stackoverflow.com/a/3038742/10299666
-
您似乎没有意识到 C# 代码只不过是生成 SQL 的工具。无论用 C# 写什么关于 LINQ 的内容,即 LINQ-to-objects,这里都不适用。如果要优化什么,那就是 SQL 代码。这就是 SQL 和映射至少与 LINQ 查询一样相关的原因。
标签: sql-server performance linq