C# LINQ Multiple GroupBy查询的执行速度比T-SQL慢几倍
我对林克完全是新手 我有一个C# LINQ Multiple GroupBy查询的执行速度比T-SQL慢几倍,c#,sql,performance,linq,group-by,C#,Sql,Performance,Linq,Group By,我对林克完全是新手 我有一个sqlgroupby,它只运行了几毫秒。但当我试图通过LINQ实现同样的目标时,它似乎太慢了。 我试图实现的是获取ceratin数据库更新的平均每月持续时间 在SQL中=> select SUBSTRING(yyyyMMdd, 0,7), AVG (duration) from (select (CONVERT(CHAR(8), mmud.logDateTime, 112)) as yyyyMMdd, DateD
sqlgroupby
,它只运行了几毫秒。但当我试图通过LINQ实现同样的目标时,它似乎太慢了。
我试图实现的是获取ceratin数据库更新的平均每月持续时间
在SQL中=>
select SUBSTRING(yyyyMMdd, 0,7),
AVG (duration)
from (select (CONVERT(CHAR(8), mmud.logDateTime, 112)) as yyyyMMdd,
DateDIFF(ms, min(mmud.logDateTime), max(mmud.logDateTime)) as duration
from mydb.mydbo.updateData mmud
left
join mydb.mydbo.updateDataKeyValue mmudkv
on mmud.updateDataid = mmudkv.updateDataId
left
join mydb.mydbo.updateDataDetailKey mmuddk
on mmudkv.updateDataDetailKeyid = mmuddk.Id
where dbname = 'MY_NEW_DB'
and mmudkv.value in ('start', 'finish')
group
by (CONVERT(CHAR(8), mmud.logDateTime, 112))
) as resultSet
group
by substring(yyyyMMdd, 0,7)
order
by substring(yyyyMMdd, 0,7)
在LINQ=>中,我首先从链接数据库名称和UpdateData信息的表中获取记录,然后对相关信息进行筛选和分组
entry.updatedata.Where(
ue => ue.updatedataKeyValue.Any(
uedkv =>
uedkv.Value.ToLower() == "starting update" ||
uedkv.Value.ToLower() == "client release"))
.Select(
ue =>
new
{
logDateTimeyyyyMMdd = ue.logDateTime.Date,
logDateTime = ue.logDateTime
})
.GroupBy(
updateDataDetail => updateDataDetail.logDateTimeyyyyMMdd)
.Select(
groupedupdatedata => new
{
UpdateDateyyyyMM = groupedupdatedata.Key.ToString("yyyyMMdd"),
Duration =
(groupedupdatedata.Max(groupMember => groupMember.logDateTime) -
groupedupdatedata.Min(groupMember => groupMember.logDateTime)
)
.TotalMilliseconds
}
).
ToList();
var updatedataMonthlyDurations =
updatedataInDateRangeWithDescriptions.GroupBy(ue => ue.UpdateDateyyyyMM.Substring(0,6))
.Select(
group =>
new updatedataMonthlyAverageDuration
{
DbName = entry.DbName,
UpdateDateyyyyMM = group.Key.Substring(0,6),
Duration =
group.Average(
gmember =>
(gmember.Duration))
}
).ToList();
我知道LINQ中的GroupBy与t-SQL中的GroupBy不同,但不确定幕后会发生什么。当我运行LINQ版本时,有人能解释一下区别和内存中发生了什么吗?在我做了.ToList()之后,在第一次GroupBy之后,事情变得更快了。但即便如此,这种寻找平均持续时间的方法也非常缓慢。
使用Visual Studio 2012改进慢LINQ语句的最佳选择是什么?有什么方法可以改进慢LINQ语句?您的LINQ查询在
LINQ to objects
中完成大部分工作。您应该构建一个linqtoentities/sql
查询,该查询一次生成完整的查询
您的查询似乎有一个冗余的GROUPBY子句,我不确定哪个表dbname
来自哪个表,但是下面的查询应该会让您走上正确的轨道
var query = from mmud in context.updateData
from mmudkv in context.updateDataKeyValue
.Where(x => mmud.updateDataid == x.updateDataId)
.DefaultIfEmpty()
from mmuddk in context.updateDataDetailKey
.Where(x => mmudkv.updateDataDetailKeyid == x.Id)
.DefaultIfEmpty()
where mmud.dbname == "MY_NEW_DB"
where mmudkv.value == "start" || mmudkv.value == "finish"
group mmud by mmud.logDateTime.Date into g
select new
{
Date = g.Key,
Average = EntityFunctions.DiffMilliseconds(g.Max(x => x.logDateTime), g.Min(x => x.logDateTime)),
};
var queryByMonth = from x in query
group x by new { x.Date.Year, x.Date.Month } into x
select new
{
Year = x.Key.Year,
Month = x.Key.Month,
Average = x.Average(y => y.Average)
};
// Single sql statement is to sent to your database
var result = queryByMonth.ToList();
如果您仍然有问题,我们需要知道您是在使用entityframework还是LINQtoSQL。您需要提供您的上下文/模型信息您应该检查生成的SQL的外观。谢谢@MarcinJuraszek。我检查了一下,结果完全不是我想象的那样。感谢LINQPad。您的linq将为我提供平均每天的持续时间。我想要每月一次。这就是为什么我有额外的groupby。我只是在学林克。所以我不知道你提到的术语=>linq->entities/linq->objects。现在用谷歌搜索它。我将尝试稍微改变一下我的方法并进行测试。谢谢你的小费。我会让你知道我的测试进展如何。对Linq to Entities有一点了解。我检查了我使用LinqPad编写的LINQ语句的SQL,似乎有100条SQL语句是在幕后为它创建的。所以我想我必须使用你给出的表达式来显式地连接实体。现在就开始测试。@eakangoplakrishnan-我把答案改成了每月平均数。非常感谢你为我指明了正确的方向。我花了一段时间。但是LinqToSql不理解某些事情,比如持续时间(datetime-datetime),它也不直接理解日期部分。但是在System.Data.Objects.SqlClient.SqlFunctions中的一些函数的帮助下,我成功地获得了所需的结果。你太棒了。虽然你的答案并不准确,但它仍然帮助我达到了目的,所以我接受它作为答案。