我该怎么做才能提高此代码的效果

时间:2015-08-03 09:57:11

标签: c# linq

我有这个代码,可以查看所有联系人,并计算每封发送给他们的电子邮件,如果他们没有打开/点击最后的X金额,那么将其返回列表< / p>

目前代码需要大约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;

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分: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);
                }
            }

}

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