计算大量数据(4000+)的排名,这些数据根据所选的日期范围和排序依据而变化

问题描述 投票:0回答:1

我有大量数据,4000 行以上。每行都与每天收集的指标数据相关联。指标表超过 110 万行。

例如:

物品表:

身份证 项目
1 你好
2 世界
... ...

公制表:

身份证 商品编号 创建日期 公制1 公制2
1 1 2024-04-20 34 21
2 1 2024-04-21 54 12
3 1 2024-04-22 32 23
4 2 2024-04-20 53 43
5 2 2024-04-21 54 23
6 2 2024-04-22 12 45
... ... ... ... ...

我需要向用户显示项目表,并附加一个“排名”列,排名将基于指标 1 数据的平均值,使问题更加复杂的是用户可以按列排序并设置日期范围。

为了计算排名,我做了以下操作:

  1. 获取某个日期范围内的所有项目及其指标数据
  2. 计算每个项目的平均 Metric 1 值
  3. 按平均值排序,索引将为我们提供与某个项目相关联的排名
  4. 如果用户按照 Metric 2 的平均值对视图表进行排序,则项目的排名不会改变

虽然这按预期工作,但它的计算成本非常高,并且需要很长时间,因为它必须迭代 4000 多行以及每行的一组指标,为了进一步添加这一点,有一个指示器可以指示它是上升还是下降通过将当前日期范围(例如 7 天范围)与其之前的日期范围(例如前 7 天)进行比较来排名,这实际上使负载加倍。

数据位于 SQL 服务器上。

有没有办法让用户的性能更高/更快? 对我来说,主要问题是有太多可变变量无法缓存/存储值。

能够按日期范围进行过滤,意味着我无法存储数据并且计算必须内联完成。

我所拥有的可以工作并且满足要求,但是它非常慢,40秒左右。 对于页面加载等更常见的请求,有预先构建的缓存。

这有效,但同样,如果用户更改 orderby 值或日期范围,则必须计算所有内容。

有没有可用的技术可以加速这种过程? 是否有任何方法可以以不同的方式存储数据以加快计算过程?

编辑

用.Net core编写的项目,使用Entity Framework

EF 查询的粗略 sudo 代码:

var dateRangeQuery = FROM Metrics in DB.Metrics 
WHERE CreatedDate > FromDate AND CreatedDate < ToDate
GROUP Metrics BY Metrics.ItemId
INTO Result select new
{
   ItemId = Result.Key,
   Metric1 = Result.Average(x => x.Metric1),
   Metric2 = Result.Average(x => x.Metric2)
}

var joinToItemsQuery = DB.Items 
Include Metrics
JOIN dateRangeQuery 
WHERE Items.Id == dateRangeQuery.ItemID

var orderQuery = joinToItemsQuery ORDERBY dateRangeQuery.Metric1
   SELECT Items

然后可以通过在 orderQuery 结果中查找项目的索引来获得排名。

写上面的内容帮助我发现了一些不必要的代码,好老橡皮鸭。

据我所知,不需要使用 dateRangeQuery 连接 Items,所以我将其删除,应该可以节省一些时间。

上面有 2 次运行两次,一次针对当前日期范围,一次针对上一个日期范围进行比较

algorithm theory computation-theory
1个回答
0
投票

如果您只是创建正确的索引,您的问题就会消失。

create unique index IdItemIdIdx on Metrics (Id, ItemId);

现在一周的数据需要 28,000 多次索引查找,而不是一遍又一遍地扫描数百万行。

如果您想在大日期范围内提高效率,请将

Metrics
表更改为
CumulativeMetrics
,其中包含以下列:

Id  ItemId  CreatedDate CountOfDates SumOfMetric1 SumOfMetric2

所有这些总和都是从开始到创建日期的所有时间。

现在您只需查看开始日期和结束日期的行即可计算日期范围。因此,现在我们可以为每个

Id
获取 3 个日期,以获取当前日期范围和上一个日期范围。无论您的日期范围有多大,这都有效。

这使得大日期范围变得高效。但请注意注意事项。您现在依赖于已正确预先计算的此表。处理超出表格日期范围的日期范围需要一定的复杂性。但如果有人查询一个月或一年的时间段,你会得到很好的加速。

© www.soinside.com 2019 - 2024. All rights reserved.