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及其传输来说是轻量级的?

Linq加入了Timstamp排序的三个表

检查以下内容,它与您所做的位于同一行,但结果包含投影的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});

以下是与您提出的问题相关的要点:

  1. 为了减少提取的列数,因为您可能不想要所有的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)

  2. 同样的另一个选项是更改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})
    
  3. 现在剩下的部分过程是CPU密集型的,使用100%的CPU,可以进行以下优化:

    • 是否每次foreach循环迭代都会调用网络Update,那么它必然会使其成为一个网络密集型过程,因此速度较慢,最好是在内存中进行所有必要的更改,然后一次性更新数据库,如果您有数百万条记录,这仍然是密集型的

即使对一百万条记录进行同样的处理也不是一个好主意,因为这将是一个相当密集的网络和CPU,因此速度较慢,您的选择是:

  • 将内存分成更小的组件,因为我不确定是否有人需要在一次更新中更新数百万条记录,所以可以进行多个较小的更新,这些更新由用户触发一个接一个地执行,但对系统资源的负担会小得多。

  • 将较小的数据集放入内存中,使用参数在数据库级别进行过滤,并在内存中传递必要的数据进行修改以进行更新。

  • 使用上面Linq中所示的投影,只带来所需的列,这将减少总体数据内存占用,势必会产生影响。

  • 如果逻辑是这样的,各种更新是互斥的,那么在线程安全结构中使用并行API进行更新,这将确保所有内核的高效快速CPU利用率,从而更快,尽管它将飙升至100%CPU,但仅为非并行执行的一小部分

除此之外,请提供我的具体细节,以帮助您了解更多细节,这些都是基本建议,没有解决此类优化问题的黄金法则