窗口函数性能开销主要来自分区和排序:分区触发重分布,无索引时内存占用上升;排序为O(n log n)每分区,键匹配联合索引可避免。优化需建最左前缀索引、慎用窗口、预计算及监控执行计划。
窗口函数的性能开销主要来自 分区(PARTITION BY) 和 排序(ORDER BY) 两个阶段,它们直接影响执行计划中的资源消耗和响应时间。
分区本身不强制排序,但会触发数据重分布(repartitioning)。数据库需按分区键对行进行分组,通常通过哈希或排序实现:
只要窗口定义中包含 ORDER BY(即使没写显式框架子句),数据库就必须为每个分区单独排序:
(user_id, event_time)),可跳过排序步骤,直接流式计算;ROWS BETWEEN 或 RANGE BETWEEN 时,多数引擎默认使用 RANGE UNBOUNDED PRECEDING,仍需排序以确定“当前行位置”。关键不是避免窗口函数,而是控制其执行路径:
PARTITION BY 列和 ORDER BY 列组成最左前缀索引;WindowAgg 节点下的 Sort 或 Hash 子节点,及其 estimated rows 与 width 是否异常。不复杂但容易忽略:一个没索引的 PARTITION BY user_id ORDER BY created_at 在千万级表上可能比等价的 GROUP BY 慢 5–10 倍。