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

动态计算时间范围的Kusto查询性能差,如何强制使用索引?

问题描述

以下查询执行速度极快:

let mostRecent = toscalar (
UserApiRequests
| summarize max(timestamp));
let twelveHoursPrior = datetime_add('hour',-12,mostRecent);
let bar = tostring(twelveHoursPrior);
let foo = todatetime('2026-03-17 08:00');
UserApiRequests
| where timestamp between (foo .. now())
| top 5 by timestamp asc 

而几乎完全相同的另一个查询性能却极差:

let mostRecent = toscalar (
UserApiRequests
| summarize max(timestamp));
let twelveHoursPrior = datetime_add('hour',-12,mostRecent);
let bar = tostring(twelveHoursPrior);
let foo = todatetime(bar);
UserApiRequests
| where timestamp between (foo .. now())
| top 5 by timestamp asc 

两个查询都看似是动态计算时间范围,但前者能锁定索引快速执行,后者却无法合理利用索引。需求是让后者的查询识别到between的日期是静态值——因为日志组件存在延迟,需要统计12小时内每小时的事件数,手动修改查询日期无法保证一致性,原以为用toscalar足够,但它仍被视为动态值,文档中也没找到明显解决方法。

解决方法
  • 移除冗余的字符串转换步骤:直接保留datetime类型变量,避免转成字符串再转回的操作,让Kusto查询优化器能识别变量的静态计算特性:

    let mostRecent = toscalar(UserApiRequests | summarize max(timestamp));
    let foo = datetime_add('hour', -12, mostRecent);
    UserApiRequests
    | where timestamp between (foo .. now())
    | top 5 by timestamp asc 
    

    这里省略了tostring和todatetime(bar)的冗余转换,foo直接为datetime类型的静态值,优化器可以基于此触发索引筛选,提升查询速度。

  • 使用materialize强制物化静态值:如果业务逻辑必须保留字符串转换步骤,可通过materialize强制在查询执行前计算出变量的具体值,让优化器将其视为静态值:

    let mostRecent = toscalar(UserApiRequests | summarize max(timestamp));
    let twelveHoursPrior = datetime_add('hour', -12, mostRecent);
    let bar = tostring(twelveHoursPrior);
    let foo = materialize(todatetime(bar));
    UserApiRequests
    | where timestamp between (foo .. now())
    | top 5 by timestamp asc 
    

    materialize会提前计算并固化foo的结果,确保优化器能基于该静态值进行索引 pruning。

内容的提问来源于stack exchange,提问作者Reginald Blue

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.11 10:22:17