Linq加入了Timstamp排序的三个表
本文关键字:三个 Timstamp 排序 Linq | 更新日期: 2023-09-27 18:19:50
我有三个表:
Sites:
Id
Timezone (string)
SiteName
Vehicles:
Id
SiteId
Name
Positions:
Id
TimestampLocal (DateTimeOffset)
VehicleId
Data1
Data2
...
Data50
单个车辆有多个位置。位置表非常大(100多密耳记录)我需要获得每辆车的最后位置(通过时间戳,因为他们可以发送旧数据)及其时区,这样我就可以根据时区进行进一步的数据处理。类似于{PositionId,VehicleId,Timezone,Data1}
我尝试过:
var result =
from ot in entities.Positions
join v in entities.Vehicles on ot.VehicleId equals v.Id
join s in entities.Sites on v.SiteId equals s.Id
group ot by ot.VehicleId into grp
select grp.OrderByDescending(g=>g.TimestampLocal).FirstOrDefault();
然后我用处理数据
foreach (var rr in result){... update Data1 field ... }
这会得到最后的值,但它确实会将所有字段都放在Positions(大量数据)中,而没有时区。此外,foreach部分非常占用CPU(因为它可能会带来数据),因为它在几秒钟内获得100%的CPU)。
林克怎么能做到这一点。。。并且对于DB及其传输来说是轻量级的?
检查以下内容,它与您所做的位于同一行,但结果包含投影的Sites
Timezone
列,它投影在Join本身中
var result =
S.Join(V,s1=>s1.Id,v1=>v1.SiteId,(s1,v1)=>new {v1.Id,s1.Timezone})
.Join(P,v1=>v1.Id,p1=>p1.VehicleId,(v1,p1)=>new {p1,v1.Timezone})
.GroupBy(g=>g.p1.VehicleId)
.Select(x=>x.OrderByDescending(y=>y.p1.TimestampLocal).FirstOrDefault())
.Select(y=>new {y.p1,y.Timezone});
以下是与您提出的问题相关的要点:
为了减少提取的列数,因为您可能不想要所有的Positions列,需要执行以下操作:
在这一行-
Join(P,v1=>v1.Id,p1=>p1.VehicleId,(v1,p1)=>new {p1,v1.Timezone})
投影字段,这些字段是Join的结果,类似于:new {p1.Id,p1.TimestampLocal,p1.VehicleId,p1.Data1,p1...,v1.Timezone}
它将只提供投影场,但随后
GroupBy
将变为GroupBy(g=>g.VehicleId)
同样的另一个选项是更改GroupBy投影,如下所示,而不是Join语句
GroupBy(g=>g.p1.VehicleId, g=>new {g.p1.Id,g.p1.TimestampLocal,g.p1.VehicleId,g.p1.Data1,g.p1...,g.Timezone})
现在剩下的部分过程是CPU密集型的,使用100%的CPU,可以进行以下优化:
- 是否每次
foreach
循环迭代都会调用网络Update
,那么它必然会使其成为一个网络密集型过程,因此速度较慢,最好是在内存中进行所有必要的更改,然后一次性更新数据库,如果您有数百万条记录,这仍然是密集型的
- 是否每次
即使对一百万条记录进行同样的处理也不是一个好主意,因为这将是一个相当密集的网络和CPU,因此速度较慢,您的选择是:
将内存分成更小的组件,因为我不确定是否有人需要在一次更新中更新数百万条记录,所以可以进行多个较小的更新,这些更新由用户触发一个接一个地执行,但对系统资源的负担会小得多。
将较小的数据集放入内存中,使用参数在数据库级别进行过滤,并在内存中传递必要的数据进行修改以进行更新。
使用上面Linq中所示的投影,只带来所需的列,这将减少总体数据内存占用,势必会产生影响。
如果逻辑是这样的,各种更新是互斥的,那么在线程安全结构中使用并行API进行更新,这将确保所有内核的高效快速CPU利用率,从而更快,尽管它将飙升至100%CPU,但仅为非并行执行的一小部分
除此之外,请提供我的具体细节,以帮助您了解更多细节,这些都是基本建议,没有解决此类优化问题的黄金法则