2015-08-03 97 views
-5

我有这段代码看起来虽然是所有联系人,并且对发送给他们的每封电子邮件进行计数,如果他们没有打开/点击最后一个X数量,然后返回它们在列表中我该怎么做才能提高此代码的性能

目前代码需要大约10分钟才能运行,有什么我可以做的改进呢?

我知道我可以限制返回的金额,但仍然很慢。

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; 
+6

先让一个性能分析器(例如dotTrace)来指导究竟什么时候缓慢。 – HimBromBeere

+0

您需要加入查询。 –

回答

0

删除.ToList()并使用IQueryables。通过使用iqueryables,代码将执行一次并减少内存。 ToList()检索所有实体并将它们存储在内存中,这是你不想要的。

0

在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); 
       } 
      } 

} 

我没有在手的时间来模拟一个数据库,并对其进行测试。此外,这种方法会在联系人和电子邮件之间进行联接,如果您每个人有100k封电子邮件,这可能是一个非常糟糕的主意。你可以通过使用rank函数来优化它,但我会说如果性能仍然不好,你可以开始考虑做db边优化,因为这个数据结构是 - 至少对我的非dba眼睛 - 并不完美适合这种查询。

+0

在sql中写这个最好的方法是什么?使用游标? – Samw

+0

确实不使用游标......如果可能;)我会查看代码并尝试更新我的答案。 – Gerino