C# 我可以做些什么来提高这段代码的性能
我有这段代码,它可以查看所有联系人,并对发送给他们的每封电子邮件进行计数,如果他们没有打开/单击最后的X金额,则将其返回到列表中 目前代码运行大约需要10分钟,我能做些什么来改进它吗 我知道我可以限制返还的金额,但这仍然很慢C# 我可以做些什么来提高这段代码的性能,c#,linq,C#,Linq,我有这段代码,它可以查看所有联系人,并对发送给他们的每封电子邮件进行计数,如果他们没有打开/单击最后的X金额,则将其返回到列表中 目前代码运行大约需要10分钟,我能做些什么来改进它吗 我知道我可以限制返还的金额,但这仍然很慢 var contactList = (from c in db.Contacts where c.Accounts_CustomerID == Account.AccountID && !c.Deleted &
var contactList =
(from c in db.Contacts
where c.Accounts_CustomerID == Account.AccountID && !c.Deleted && !c.EmailOptOut
select c).ToList();
foreach (var person in contactList)
{
var SentEmails =
(from c in db.Comms_Emails_EmailsSents where c.ContactID == person.ID select c).OrderBy(
x => x.DateSent).Take(Last).ToList();
if (SentEmails.Count == Last)
{
if (!Clicks)
{
if (SentEmails.Count(x => x.Opens == 0) == Last)
{
ReturnContacts.Add(person);
}
}
else
{
if (SentEmails.Count(x => x.Clicks == 0) == Last)
{
ReturnContacts.Add(person);
}
}
}
}
return ReturnContacts;
删除.ToList()并使用iQueryTables。通过使用iqueryables,代码将执行一次并减少内存。ToList()检索所有实体并将它们存储在内存中,这是您不需要的。在db上运行逻辑-使用联接等重写查询,以便返回已包含相关数据的结果集 现在要做的是对每个初始查询结果执行db查询。这可能意味着有很多疑问 如果您将其卸载到RDBMS中,您可以随时尝试并优化它(通过引入索引等) 编辑:我在记事本中重写了代码:
foreach(var record in (from c in db.Contacts
join es in db.Comms_Emails_EmailsSents
on c.Id equals es.ContactId
where c.Accounts_CustomerID == Account.AccountID && !c.Deleted && !c.EmailOptOut
orderby c.Id, es.DateSent descending
select new {opens=es.Opens, clicks=es.Clicks, person=c})
.GroupBy(r=>r.person)){
var mails = record.Take(Last).ToList();
if(mails.Count == Last){
if(!Clicks){
if(mails.Count(x=>x.opens == 0) == Last){
ReturnContacts.Add(record.Key);
}
}
}else
{
if (SentEmails.Count(x => x.Clicks == 0) == Last)
{
ReturnContacts.Add(record.Key);
}
}
}
我手头没有时间来模拟db并测试它。此外,这种方法在联系人和电子邮件之间执行连接,如果你每人有10万封电子邮件,这可能是一个非常糟糕的主意。您可以使用秩函数对其进行优化,但我想说,如果性能仍然很差,您可以开始考虑进行数据库端优化,因为这种数据结构——至少在我的非dba眼中——并不完全适合这种查询。使用性能分析器(例如dotTrace)首先,让我们了解一下到底什么进展缓慢。您需要一个连接查询。用sql编写此查询的最佳方法是什么?使用游标?完全不使用游标。。。如有可能;)我将查看代码并尝试更新我的答案。