加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

聚合(分组)如何在SQL Server上工作?

发布时间:2020-12-13 20:11:17 所属栏目:百科 来源:网络整理
导读:SQL Server如何实现group by子句(聚合)? 作为灵感,采取this question’s查询的执行计划: select p_id,DATEDIFF(D,MIN(TreatmentDate),MAX(TreatmentDate)) from patientsTable group by p_id 在查询数据之前,简单的select语句及其执行计划是这样的: 使用
SQL Server如何实现group by子句(聚合)?

作为灵感,采取this question’s查询的执行计划:

select p_id,DATEDIFF(D,MIN(TreatmentDate),MAX(TreatmentDate)) from 
patientsTable group by p_id

在查询数据之前,简单的select语句及其执行计划是这样的:

使用查询和执行计划检索数据后:

通常它是Stream Aggregate或Hash Aggregate.

> Stream aggregate对结果集进行排序,扫描并返回每个新值(不等于扫描中的最后一个值).它允许保留一组聚合状态变量.
>哈希聚合从结果集构建哈希表.每个条目保留聚合状态变量,这些变量在散列未命中时初始化并在散列命中时更新.

让我们看看AVG是如何工作的.它需要两个状态变量:sum和count

grouper  value
1        4
1        3
2        8
1        7
2        1
1        2
2        6
2        3

流聚合

>首先,它需要对值进行排序:

grouper  value
1        4
1        3
1        7
1        2
2        8
2        1
2        6
2        3

>然后,它保留一组状态变量,初始化为0,并扫描排序的结果集:

石斑鱼价值总和
– 进入
– 变量:0 0
1 4 4 1
1 3 7 2
1 7 14 3
1 2 16 4
– 集团变更.返回结果并重新初始化变量
– 返回1,4
– 变量:0 0
2 8 8 1
2 1 9 2
2 6 15 3
2 3 18 4
– 集团变更.返回结果并重新初始化变量
– 返回2,4.5
– 结束

哈希聚合

>只需扫描值并将状态变量保留在哈希表中:

grouper  value
-- Hash miss. Adding new entry to the hash table
--             [1] (0,0)
-- ... and updating it:
1        4     [1] (4,1)
-- Hash hit. Updating the entry:
1        3     [1] (7,2)
-- Hash miss. Adding new entry to the hash table
--             [1] (7,2)  [2] (0,0)
-- ... and updating it:
2        8     [1] (7,2)  [2] (8,1)
1        7     [1] (14,3)  [2] (8,1)
2        1     [1] (14,3)  [2] (9,2)
1        2     [1] (16,4)  [2] (9,2)
2        6     [1] (16,4)  [2] (15,3)
2        3     [1] (16,4)  [2] (18,4)
-- Scanning the hash table and returning the aggregated values
-- 1   4
-- 2   4.5

通常,如果结果集已经排序,则排序更快(例如,值来自索引或由前一操作排序的结果集).

散列更快是结果集未排序(散列比排序更快).

MIN和MAX是特殊情况,因为它们不需要扫描整个组:只有组内聚合列的第一个和最后一个值.

不幸的是,与大多数其他系统不同,SQL Server无法有效利用它,因为它不适合进行INDEX SKIP SCAN(跳过不同的索引键).

虽然简单的MAX和MIN(没有GROUP BY子句)如果聚合列上的索引存在,则使用TOP方法,而带有GROUP BY的MIN和MAX使用与其他聚合函数相同的方法.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读