如何使用KQL/ADX高效计算非频繁数据的小时平均值
传感器数据小时平均值计算优化问题
我需要为仅在数据变化时上报的传感器数据计算小时平均值,部分场景下数据上报间隔长达6小时(心跳间隔)。
常规方法的问题
常规使用summarize按小时聚合的写法如下:
T | summarize avg(value) by bin(timestamp, 1h), systemID
该方法存在两个核心问题:
- 部分时间区间无数据时会产生空值,预期空值时段应沿用之前最后一次上报的值;
- 若每小时内数据变化次数少,计算结果精度不足。
举个例子:
datatable(timestamp:datetime, value:double, id:string) [ datetime('2023-05-08T00:00:00Z'), 0, 'test', datetime('2023-05-08T00:01:00Z'), 1, 'test', datetime('2023-05-08T00:02:00Z'), 2, 'test', datetime('2023-05-08T03:00:00Z'), 3, 'test'] | summarize avg(value) by bin(timestamp, 1h), id
查询返回结果:
timestamp id avg_value 2023-05-08T00:00:00Z test 1 2023-05-08T03:00:00Z test 3
但00:00时段更准确的值应为2,因为该值是最后一次上报且在剩余时段生效。
当前解决方案的内存问题
为解决上述问题,我编写了使用make-series和series_fill_forward的查询:
let series_step = 10m; let results_bin = 1h; let series_length = 2d; let lookback = 1d; T | make-series hint.shufflekey=systemID average=avg(value) default=double(null) on timestamp from ago(series_length+lookback) to now() step series_step by systemID | extend fillforward = series_fill_forward(average) | mv-expand timestamp, fillforward | project systemID, fillforward = todouble(fillforward), timestamp = todatetime(timestamp) | order by timestamp asc | summarize hint.shufflekey=systemID average = avg(fillforward) by bin(timestamp, results_bin), systemID
该查询虽符合预期,但内存占用是常规方法的5倍以上,且增大series_length到30天时会触发内存不足错误:
Partial query failure: Low memory condition (E_LOW_MEMORY_CONDITION). (message: 'bad allocation', details: '')
我的最终目标是构建30天小时聚合数据的物化视图,请问如何优化该方案?
内容的提问来源于stack exchange,提问作者Ville
相关产品推荐
相关产品推荐

