Query Transformation- Distinct Aggregate Transformation

GROUP BY操作是数据库中非常常见的语法,通常用于聚合函数的聚合操作。对于oracle最早的时候对于group by还是使用的Sort Group Aggregate,之后引入了一种对于大数据量group by较为高效的算法Hash Group Aggregate。

该特性由参数“_gby_hash_aggregation_enabled”控制,也可以使用hint USE_HASH_AGGREGATION/NO_USE_HASH_AGGREGATION来控制。目前绝大部分的group by算法几乎都是Hash Group Aggregate。

当然也有Sort Group Aggregate的使用场景,就是当语句出现group by xxx order by xxx的时候

当然使用hint也可以让group by +order by走Hash Group Aggregate+Sort Order By

介绍了一下SORT/HASH group by,下面是这篇文章的主题,当聚合操作里出现distinct时,如count(distinct xxx)时,其他数据库是不能使用Hash Group Aggregate的。以海量的vastbase为例:

而oracle 从11gr2版本开始,CBO应对这种场景会对sql进行转换,生成一个DAG inline view,并且会多做一次Hash Group Aggregate。这个查询转换叫做Distinct Aggregate Transformation,由参数“_optimizer_distinct_agg_transform”控制,也可以使用hint TRANSFORM_DISTINCT_AGG/NO_TRANSFORM_DISTINCT_AGG 在sql级别控制。

先来看看oracle的执行计划:

可以看到中间生成了一个DAG VIEW,并且执行计划出现了两次HASH GROUP BY,并未出现SORT GROUP BY。

从10053 可以发现oracle会做一个DAGG_TRANSFORM转换,将sql进行改写

格式化一下转换后的sql

其原理就是先构造一个inline view对distinct的字段也做group by 形成一个DAG view,再对DAG view生成等价的改写。巧妙的避开了distinct造成的不能HASH GROUP BY的场景。非常值得国产数据库学习,应该目前很少有国产数据库会支持该特性。

 

 

 

此条目发表在Oracle, Oralce performance分类目录,贴了, , 标签。将固定链接加入收藏夹。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注