【发布时间】:2012-09-18 18:03:03
【问题描述】:
前段时间我问了SQL Server: How do I maintain data integrity using aggregate functions with group by?这个问题,我在那里得到了很好的答案,但现在问题又出现了,这次是Linq to SQL,而不是普通的SQL。
背景故事:我有一个完整的 gps 数据表,如下所示:
GPS_id、user_id、纬度、经度、server_time、device_time
我使用以下 linq 查询来提取特定用户组的最新 gps 记录:
var query =
from gps in db.gps_data
where (from u in db.users
select u.user_id).Contains(gps.user_id)
group gps by gps.user_id into groupedGPS
select groupedGPS;
然后我像这样循环遍历它,但我必须先订购它才能正确抓取“最新记录”。
foreach (var gpsItem in query) {
var ordered = gpsItem.OrderByDescending(g => g.device_time);
list.Add(ordered.First());
}
这给了我我需要的东西,但在任何时候我都有 100 多个用户,他们都拥有 500 多条 gps 记录(并且所有这些用户都以这种方式访问),所以这段代码需要 10 多秒,我认为这是不可接受的。
然后我把它改成了下面的
var query =
from gps in db.gps_data
where (from u in db.users
select u.user_id).Contains(gps.user_id)
group gps by gps.user_id into groupedGPS
select new
{
GPS_id = groupedGPS.Max(x => x.GPS_id),
user_id = groupedGPS.Max(x => x.user_id),
latitude = groupedGPS.Max(x => x.latitude),
longitude = groupedGPS.Max(x => x.longitude),
server_time = groupedGPS.Max(x => x.server_time),
device_time = groupedGPS.Max(x => x.device_time)
};
这个查询看起来确实更快,因为据我了解,所有不必要的数据实际上从未加载到内存中。但是,就像几个月前我最初的问题一样,我已经以这种方式失去了数据完整性。不能保证我看到的是最新的记录,只是分组中所有字段的最大值。这对大多数字段没有影响,但纬度和经度几乎总是不正确的,因为它们只是在分组中找到的 max() 记录,而不是最近的记录。
如何解决这个问题?我意识到我有第一个解决方案来检索我正确的数据,但是花费的时间太长了。
感谢您的帮助!
【问题讨论】:
标签: c# sql linq-to-sql query-optimization