【发布时间】:2015-04-11 11:08:33
【问题描述】:
我有这个来自在 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 查询?
【问题讨论】:
-
你有没有机会把上面的查询转成存储过程并返回结果并显示在网格中?如果是,那是更有效的方法
-
grp.FirstOrDefauilt()看起来很可疑 - 你不是说grp.Key吗?另外,为什么不是dateAdd传递的参数,而不是数据库中的值?这应该允许您在createdAt上使用索引(如果有的话)。 -
能否告诉我们生成的 LINQ 查询是什么样的?
-
我在您的 Linq 版本中找不到条件“createdAt
标签: c# .net sql-server linq