首页 > 解决方案 > 在这种情况下,EF Core 生成的 SQL 效率很低,有什么解决方法吗?

问题描述

采取这样简单的实体:

public class Person
{
    public int Id { get; set; }
    public string MainEmail { get; set; }
}

public class Person_Email
{
    public int Id { get; set; }
    public int Id_Person { get; set; }
    public string Email { get; set; }
} 

这个查询:

db.Person.Where(p => p.Person_Email.Any(c => c.Email == "myemail@email.com") || p.MainEmail == "myemail@email.com").FirstOrDefault();

被翻译为:

SELECT TOP(1) [p].[Id]
FROM [Person] AS [p]

WHERE (EXISTS (
    SELECT 1
    FROM [Person_Email] AS [p1]
    WHERE ([p].[Id] = [p1].[Id_Person]) AND ([p1].[Email] = N'myemail@email.com')) 
    OR ([p].[MainEmail] = N'myemail@email.com')
    )

这非常慢,在我的数据库上,分析器说 4347316 读取和 2568 持续时间)。

我会将sql写为:

SELECT TOP(1) [p].[Id]
FROM [Person] AS [p]

join [Person_Email] as pe on p.Id = pe.Id_Person
where p.MainEmail = N'myemail@email.com' or pe.Email = N'myemail@email.com'

在这种情况下,分析器显示 17448 次读取和 300 次持续时间。

我想知道是否有办法以不同的方式优化编写 LINQ 查询,或者我们可以等待 ef 核心团队改进它(我尝试了 ef core 5.0 preview 8 并且没有任何改变)。

标签: c#entity-framework-core

解决方案


这个怎么样?

var person = (from a in db.Person
              from b in db.Person_Email.Where(c => c.Id_Person == a.Id).DefaultIfEmpty()
              where a.MainEmail == "myemail@email.com" || b.Email == "myemail@email.com"
              select a).FirstOrDefault();

或者

var personemail = db.Person_Email.Where(c => c.Email == "myemail@email.com").FirstOrDefault();

var person = db.Person.Where(c => (personemail == null || c.Id == personemail.Id_Person) || c.MainEmail == "myemail@email.com").FirstOrDefault();

在此处输入图像描述


推荐阅读