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

为何GROUP BY查询可利用索引,而SUM窗口函数查询无法使用索引?

性能差异原因解析

查询1b(GROUP BY方案)快的核心原因

数据库优化器支持谓词下推,你外层的where wonum = 'WO360996'里的wonum是子查询中wogroup的别名,优化器可以直接将过滤条件下沉到内层的GROUP BY逻辑之前,执行顺序变成:

  1. 先走WORKORDER_NDX32索引范围扫描,定位所有wogroup = 'WO360996'的行(也就是目标工单和它的所有子任务,一般只有寥寥几行)
  2. 对这少量行直接做分组聚合,因为索引本身是有序的,分组不需要额外排序(执行计划里的SORT GROUP BY NOSORT就是这个意思)
    整个过程只扫描了个位数的行,自然只需要几十毫秒。

查询2(窗口函数方案)慢的核心原因

窗口函数的逻辑优先级高于外层过滤,且优化器无法做谓词下推:

  1. 你定义的窗口函数是partition by wogroup,需要对每个wogroup分区的所有行计算SUM值,而你外层的过滤条件是针对wonum字段的,wonum和wogroup不是同一个字段,优化器无法推断出你只需要wogroup = 'WO360996'这个分区的计算结果
  2. 所以执行时只能先全表扫描所有35万行WORKORDER数据,给所有行都计算完窗口函数的SUM结果,最后才过滤出你要的那一行
    等于白白计算了35万行的聚合值,耗时自然飙升到秒级。

窗口函数的优化思路

如果要让窗口函数版本也走索引,可以主动把wogroup的过滤条件加到最内层:

select *
from (
    select
        wonum,
        actlabcost_tasks_incl,
        actmatcost_tasks_incl,
        acttoolcost_tasks_incl,
        actservcost_tasks_incl,
        acttotalcost_tasks_incl,
        other_wo_columns
    from (
        select
            wonum,
            istask,
            sum(actlabcost ) over (partition by wogroup) as actlabcost_tasks_incl,
            sum(actmatcost ) over (partition by wogroup) as actmatcost_tasks_incl,
            sum(acttoolcost) over (partition by wogroup) as acttoolcost_tasks_incl,
            sum(actservcost) over (partition by wogroup) as actservcost_tasks_incl,
            sum(actlabcost + actmatcost + acttoolcost + actservcost) over (partition by wogroup) as acttotalcost_tasks_incl,
            rowstamp as other_wo_columns
        from maximo.workorder
        -- 主动加wogroup过滤,引导优化器走索引
        where wogroup = (select wogroup from maximo.workorder where wonum = 'WO360996')
    )
    where istask = 0
)
where wonum in ('WO360996')

修改后也能走WORKORDER_NDX32索引,性能和GROUP BY版本基本一致。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 10:15:04