c# – LINQ查询中的性能降低

我有这个来自在Cold Fusion上运行的旧系统的t-sql查询.此查询返回记录所需的时间不到一秒.

select  dateDiff(month, dateAdd(hour, 11, createdAt), {ts '2015-02-28 23:59:59'}) p, count(*) c 
from    account 
where   createdAt <= {ts '2015-02-28 23:59:59'} 
and accountType = 'business' 
and dateDiff(month, dateAdd(hour, 11, createdAt), {ts '2015-02-28 23:59:59'}) <12 
group by    dateDiff(month, dateAdd(hour, 11, createdAt), {ts '2015-02-28 23:59:59'}) 
order by    dateDiff(month, dateAdd(hour, 11, createdAt), {ts '2015-02-28 23:59:59'})

我现在使用.NET和LINQ将其转换为新系统.
我设法写了这个LINQ查询,它给了我相同的结果.

from a in db.Accounts
where SqlFunctions.DateDiff("Month", SqlFunctions.DateAdd("Hour", 11, a.createdAt), "2015-02-28 23:59:59") < 12
&& a.accountType == "business"
group a by SqlFunctions.DateDiff("Month", a.createdAt, "2015-02-28 23:59:59") into grp
orderby SqlFunctions.DateDiff("Month", grp.FirstOrDefault().createdAt, "2015-02-28 23:59:59")
select new ProgressViewModel.Data
{
     date = SqlFunctions.DateDiff("Month", grp.FirstOrDefault().createdAt, "2015-02-28 23:59:59"),
     amount = grp.Count()
});

但是,此查询运行时间不少于5秒,而第一个查询(t-sql)则需要不到1秒.

通过使用Glimpse,我们可以看到LINQ查询生成的t-sql.它有多个子选择,比快速查询长5倍.

我怎样才能改进LINQ查询?

最佳答案 我真的怀疑你真的想在你的代码中的任何一点使用FirstOrDefault().

BTW看起来您正在使用LinqToSQL作为您的Linq提供商.那东西是讨厌,低效和彻头彻尾的马车.如果可能的话,你应该切换到EntityFramework

鉴于……也许你应该尝试这个……

var date = new Date(2015, 2, 28).AddDays(1);
var query = from account in context.Accounts
            where account.CreatedAt < date
            where account.accountType == "business"
            group account by 
                   SqlFunctions.DateDiff(
                            "Month", 
                             SqlFunctions.DateAdd(
                                   "Hour", 11, a.createdAt), 
                             date)
            into g
            where g.Key < 12
            order by g.Key ascending
            select new 
            {
                MonthsAgo = g.Key,
                Count = g.Count(),
            };
点赞