【发布时间】:2015-12-20 23:12:48
【问题描述】:
Entity Framework 为以下 LINQ 查询生成性能非常差的 SQL:
var query = _context.Sessions
.Where(s => s.OrganizationId == orgId && s.Device != null && s.Device.User != null)
.Select(s => s.Device.User)
.Distinct();
生成此 SQL:
exec sp_executesql N'SELECT
[Distinct1].[Id] AS [Id],
[Distinct1].[Email] AS [Email],
[Distinct1].[Sex] AS [Sex],
[Distinct1].[Age] AS [Age]
FROM ( SELECT DISTINCT
[Extent4].[Id] AS [Id],
[Extent4].[Email] AS [Email],
[Extent4].[Sex] AS [Sex],
[Extent4].[Age] AS [Age]
FROM (SELECT [Extent1].[OrganizationId] AS [OrganizationId], [Extent3].[UserId] AS [UserId1]
FROM [dbo].[Sessions] AS [Extent1]
INNER JOIN [dbo].[Devices] AS [Extent2] ON [Extent1].[DeviceId] = [Extent2].[Id]
LEFT OUTER JOIN [dbo].[Devices] AS [Extent3] ON [Extent1].[DeviceId] = [Extent3].[Id]
WHERE [Extent2].[UserId] IS NOT NULL ) AS [Filter1]
LEFT OUTER JOIN [dbo].[Users] AS [Extent4] ON [Filter1].[UserId1] = [Extent4].[Id]
WHERE [Filter1].[OrganizationId] = @p__linq__0
) AS [Distinct1]',N'@p__linq__0 int',@p__linq__0=2
我实际上要执行的 SQL 如下,它运行得很快:
select distinct u.*
from Sessions s
inner join Devices d on s.DeviceId = d.Id
inner join Users u on d.UserId = u.Id
where OrganizationId = 2
如何让实体框架生成的 SQL 尽可能接近这个查询?
【问题讨论】:
-
看来你需要
.Select(s => s.Device.User.Email) -
这些不是等效的查询,所以难怪它们的执行方式会有所不同。
-
最后一个(已编辑的)SQL 查询如何执行?
-
能否确认编辑后手动SQL查询还是很快的?
-
我随身携带了一位经验丰富的 DBA 的明智建议,该建议至少已被我多次证明。如果您的查询中有 DISTINCT,则说明有问题。这个查询可以用不同的方式进行,不需要 DISTINCT。
标签: c# entity-framework linq linq-to-entities