我正在使用 Entity Framework Core。使用此代码,获取 2000 条记录需要 1 分钟多的时间。 请帮我在几秒钟内找到数据。
var incomingEmails = acompDbContext.IncomingEmails.AsNoTracking().Where(ie => ie.ReceiverRuc == req.ReceiverRuc)
.Select(ie => new IncomingEmail
{
// Select only necessary properties
IncomingEmailId = ie.IncomingEmailId,
IdStatusMail = ie.IdStatusMail,
MessageId = ie.MessageId,
From = ie.From,
To = ie.To,
Subject = ie.Subject,
Body = ie.Body,
AttachmentName = ie.AttachmentName,
Attachment = ie.Attachment,
AttachmentType = ie.AttachmentType,
AttachmentId = ie.AttachmentId,
EmitterRuc = ie.EmitterRuc,
EmitterBusinessName = ie.EmitterBusinessName,
ReceiverRuc = ie.ReceiverRuc,
Date = ie.Date,
Valid = ie.Valid
}).ToListAsync();
我尝试减少数据,但我需要全部 2000 条记录。
我想到三件事。首先检查此 ReceiverRuc 列是否已在数据库中建立索引。针对非索引列查询数据会更慢,尤其是对于包含大量数据的表。
其次,这个查询似乎确实提取了更多它可能应该提取的信息。我看到的警告标志是电子邮件正文和附件。当拉动数千行进行迭代时,请考虑省略那些不是“立即”必要的重量级字段。如果您确实希望最终迭代所有 2000 个结果,您可以通过 ID 获取这些繁重的字段,甚至可以将它们批量化,并在处理电子邮件记录时一次获取 10 或 100 个较小的组。 第三是附件本身,这是电子邮件表中的一列还是单独附件表中的一行?如果是后者,您将希望将其投影到简化的附件对象,同样只包含您需要的列:
.Select(ie => new IncomingEmail
{
// Select only necessary properties
// ...
Attachment = new Attachment { ... }
// ...
}).ToListAsync();
如果您使用 ToListAsync(),查询本身需要
await
。
为了了解正在发生的情况,您可以做的下一件事是针对数据库运行探查器以捕获正在运行的 SQL 语句。需要注意的罪魁祸首是诸如延迟加载调用之类的事情。例如,如果您启动此方法并捕获一条似乎从电子邮件加载数据的 SQL 行,但随后看到 2000 条左右的附加 SQL 语句提取与附件周围某个表相关的数据(假设附件是另一个表中的一行) )那么您可能会遇到延迟加载引用所包含的附件实体的问题。这个问题本身可以通过将附件投影到新容器中来解决。 (上面的第三点)不过,在读取数据时,分析器可以帮助识别与延迟加载相关的性能问题。您还可以检查实际运行的 SQL 语句以获得执行计划,该计划可以提供性能提示。