[英]Linq making very inefficient Entity Framework query
Entity Framework generates very poorly performing SQL for the following LINQ query: 实体框架为以下LINQ查询生成性能非常差的SQL:
var query = _context.Sessions
.Where(s => s.OrganizationId == orgId && s.Device != null && s.Device.User != null)
.Select(s => s.Device.User)
.Distinct();
Generates this SQL: 生成这个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
The SQL I'm actually looking to execute is the following, which runs lightning fast: 我实际上想要执行的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
How can I get the Entity Framework-generated SQL to be as close to this query as possible? 如何让Entity Framework生成的SQL尽可能接近此查询?
Why select the whole User
entity if you just want the email? 如果您只想要电子邮件,为什么选择整个
User
实体?
Try this: 尝试这个:
var query = _context.Sessions
.Where(s => s.OrganizationId == orgId && s.Device != null && s.Device.User != null)
.Select(s => s.Device.User.Email)
.Distinct();
Try starting with the users table: 尝试从users表开始:
var query = (
from u in _context.Users
where u.Devices.Any(d => d.Sessions
.Any(s => s.OrganisationId == orgId)
)
select u
);
It won't do the query you specified but what it does return might have the same good performance. 它不会执行您指定的查询,但它返回的内容可能具有相同的良好性能。
You can do it pretty simply: 你可以很简单地做到:
_context.Sessions
.Where(s => s.OrganizationId == 2)
.Select(s => s.Device.User)
.Distinct();
You do not need to check for null
, as it will perform an INNER JOIN
for you. 您不需要检查
null
,因为它将为您执行INNER JOIN
。
I dont like use the DISTINCT , if a query contains it then the query's wrong. 我不喜欢使用DISTINCT,如果查询包含它,那么查询是错误的。
Other way to do it 其他方式来做到这一点
var query = _context.Sessions.Include("Device.User.Email")
.Where(s => s.OrganizationId == orgId);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.