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

理解SQL Server执行计划:Sort、Stream Aggregate等操作相关疑问

你提供的查询语句如下:

SELECT TOP 1000
    fact.division,
    case when fact.division='east' then 'XXX' else 'YYY' end div,
    count(1)
FROM
    division join fact on (division.division=fact.division) 
where
    fact.division!='east'
group by
    fact.division

对应的执行计划示意图:
执行计划示意图


问题1:为什么聚合操作前会先执行Sort操作?

SQL Server的Stream Aggregate算子要求输入数据集必须按照分组列有序,才能按顺序连续读取同分组的行完成聚合,不需要额外内存缓存分组哈希表。
你的查询按fact.division分组,而join后的结果集没有按该列排序的索引支撑,所以优化器会在流聚合前插入Sort算子,将结果集按分组列排序,适配流聚合的执行要求。

问题2:为什么会有两个Stream Aggregate操作?

这是SQL Server优化器的预聚合优化策略:

  • 第一个Stream Aggregate是在fact表完成过滤后、join操作前执行,先按fact.division做一次局部聚合统计计数,大幅减少需要参与join的行数,降低join阶段的IO和计算开销
  • 第二个Stream Aggregate是在join完成后,对关联后的结果做最终的全局聚合,合并预聚合的计数结果

这种拆分比直接将所有明细行join后再做一次聚合的性能高很多,是典型的关联场景下的聚合优化手段。

问题3:两个Compute Scalar操作的作用是什么?如何查看具体计算逻辑?

两个Compute Scalar分别对应不同阶段的标量计算:

  • 第一个一般位于预聚合阶段之后,用于计算预聚合输出的衍生值(比如计数的中间常量转换)
  • 第二个位于最终聚合之后,用于执行你查询中写的CASE WHEN逻辑,生成div列的输出值,因为该列不需要参与分组和关联,只需要在最终输出前计算即可。

如果悬浮提示信息模糊,你可以右键点击对应的Compute Scalar算子,选择「属性」,在属性面板中找到定义的值(Defined Values) 选项,展开后就能看到该算子所有输出列对应的完整计算表达式,所有计算逻辑都可以明确查到。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 13:45:03