我有这个来自在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(),
};