You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让ADX/KQL中源表与物化视图的百分位数值一致?

解决物化视图分层计算百分位数的差异问题

已通过物化视图从源表生成聚合表,但发现直接从源表计算的百分位数与从聚合表(实际场景中stg01为源表的物化视图)计算的结果存在差异,以下是问题复现代码及解决方案:

源表直接计算百分位数的代码

let MySourceTable = datatable(col1:int, col2:int, Value:int, EventUTCDateTime:datetime)
[
1,2,10,'2022-01-01 01:00:01',
1,2,20,'2022-01-01 02:01:01',
1,2,30,'2022-01-01 03:05:01',
1,2,40,'2022-01-02 01:30:01',
1,2,20,'2022-01-02 02:30:01',
1,2,50,'2022-01-03 07:30:01',
1,2,50,'2022-01-05 06:30:01'
];
MySourceTable
| extend EventUTCDate = bin(EventUTCDateTime,30m)
| project col1,col2,Value,EventUTCDate
| summarize RecordsCount=count(), TotalValue=sum(Value), Min=min(Value), Max=max(Value),Median=percentile(Value,50) by col1,col2
| project col1,col2, Mean=TotalValue/RecordsCount, Min, Max,Median

聚合表分层计算百分位数的代码(存在差异)

let MySourceTable = datatable(col1:int, col2:int, Value:int, EventUTCDateTime:datetime)
[
1,2,10,'2022-01-01 01:00:01',
1,2,20,'2022-01-01 02:01:01',
1,2,30,'2022-01-01 03:05:01',
1,2,40,'2022-01-02 01:30:01',
1,2,20,'2022-01-02 02:30:01',
1,2,50,'2022-01-03 07:30:01',
1,2,50,'2022-01-05 06:30:01'
];
let stg01 = MySourceTable
| extend EventUTCDate = bin(EventUTCDateTime,1d)
| project col1,col2,Value,EventUTCDate
| summarize RecordsCount=count(), TotalValue=sum(Value), Min=min(Value), Max=max(Value),Median=percentile(Value,50) by col1,col2,EventUTCDate;
stg01
| summarize RecordsCount=sum(RecordsCount), TotalValue=sum(TotalValue),Min=min(Min), Max=max(Max),Median=percentile(Median,50) by col1,col2
| project col1,col2, Mean=TotalValue/RecordsCount, Min, Max,Median 

问题原因

百分位数的计算依赖全量数据的排序分布,直接对分层计算出的百分位数再做聚合,本质是对"分组百分位数"的二次统计,丢失了原始数据的完整分布信息,必然和全局百分位数存在差异。

解决方案

方案1:使用tdigest类型实现增量式百分位数计算

tdigest是Kusto中用于高效计算近似百分位数的数据结构,支持合并操作。可以在物化视图中存储每个分组的tdigest,后续全局聚合时合并这些tdigest再计算百分位数,结果与直接从源表计算一致。

修正后的聚合表计算代码

let MySourceTable = datatable(col1:int, col2:int, Value:int, EventUTCDateTime:datetime)
[
1,2,10,'2022-01-01 01:00:01',
1,2,20,'2022-01-01 02:01:01',
1,2,30,'2022-01-01 03:05:01',
1,2,40,'2022-01-02 01:30:01',
1,2,20,'2022-01-02 02:30:01',
1,2,50,'2022-01-03 07:30:01',
1,2,50,'2022-01-05 06:30:01'
];
// 物化视图层:存储每个日分组的tdigest及其他聚合指标
let stg01 = MySourceTable
| extend EventUTCDate = bin(EventUTCDateTime,1d)
| project col1,col2,Value,EventUTCDate
| summarize 
    RecordsCount=count(), 
    TotalValue=sum(Value), 
    Min=min(Value), 
    Max=max(Value),
    ValueTdigest=tdigest(Value)  // 存储tdigest结构
by col1,col2,EventUTCDate;
// 全局聚合层:合并tdigest后计算百分位数
stg01
| summarize 
    RecordsCount=sum(RecordsCount), 
    TotalValue=sum(TotalValue),
    Min=min(Min), 
    Max=max(Max),
    Median=percentile_tdigest(merge_tdigests(ValueTdigest), 50)  // 合并tdigest并计算中位数
by col1,col2
| project col1,col2, Mean=TotalValue/RecordsCount, Min, Max,Median 

方案2:调整物化视图粒度(仅适用于数据量不大的场景)

如果数据量允许,可以将物化视图的聚合粒度调整到与最终全局聚合一致,避免分层二次统计;或者在物化视图中保留原始数据的分组统计(比如用make_list(Value)存储每个分组的所有值),但这种方法会占用大量存储,仅适合小数据场景。


内容的提问来源于stack exchange,提问作者Brahmaiah Takkellapati

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 09:34:55