c# - 在这种情况下,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 并且没有任何改变)。
解决方案
这个怎么样?
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();
推荐阅读
- rust - 当堆数据的所有者超出范围时,编译如何丢弃它?
- python - 是否可以在加载数据时格式化 Datatable.js 表?
- azure - 您能否举例说明 Microsoft Azure 中的 Append Blob?
- css-grid - 如何在 webcomponents 中封装父子关系?
- google-apps-script - 使用谷歌应用脚本(REST API)获取 woocommerce json 订单元数据键值
- python - indices[117,181] = -1 不在 [0, 250) 中,使用 Elmo 和 LSTM
- typescript - 类型 { new (fileBits: BlobPart[], fileName: string, options?: FilePropertyBag | undefined):File; 上不存在属性“create”。原型:文件}
- flutter - 当用户点击通知时颤动网络深度链接
- reactjs - 使用钩子在反应中改变两种状态后执行代码
- windows - 用空格重命名所有文件的批处理脚本