【数据库内核】物理算子之Distinct算子实现

目录

概述

Sort Distinct算法

一、原理和伪代码描述

<1> 原理

<2> 伪代码描述

二、案例

Hash Distinct算法

一、原理和伪代码描述

<1> 原理

<2> 伪代码描述

二、案例

Distinct 语义优化

简单distinct语句优化

聚合函数distinct优化

结论


概述

DISTINCT实际上和GROUP BY的操作非常相似,只不过是在GROUP BY之后的每组中只取出一条记录而已。所以,DISTINCT的实现和GROUP BY的实现也基本差不多,没有太大的区别。

名词介绍

  • Scan,作用是读取数据源的具体数据。例如: select * from t 就是读取t表中的数据。
  • OutPut,作用是物理执行器计算出的数据传递给外部。例如: select c from t 中 OutPut算子是输出C列中的数据。
  • Distinct, 作用是计算的数据去重操作。例如: select distinct c1 from t 中t表中c1字段的数据去重输出。
  • Aggregate, 作用是数据聚合功能。例如: select sum(c1) from t 中t表中c1字段中的数据求和。
  • Exchange, 网络数据接收器。

 

Sort Distinct算法

一、原理和伪代码描述

<1> 原理

Sort Distinct的计算需要保证输入数据按照Order-By列有序。在计算过程中,每当读到一个新的Group 的值或所有数据输入完成时,便对前一个Group的进行去重计算。

Sort Distinct的输入数据需要保证同一个Group的数据连续输入,所以Stream Distinct处理完一个Group的数据后可以立刻向上返回结果,不用像Hash Distinct一样需要处理完所有数据后才能正确的对外返回结果。

 

<2> 伪代码描述

clear the current distinct results clear the current order by columns for each input row   begin     if the input row does not match the current order by columns       begin         output the distinct results         clear the current distinct results         set the current order by columns to the input row       end     update the distinct results with the input row   end

 

二、案例

测试SQL如下所示

SELECT  distinct departIdFROM  staff_ORDER BY   departId

Oracle计划显示如下:

 

算法推演如下:

 

 

Hash Distinct算法

一、原理和伪代码描述

<1> 原理

在 Hash Distinct 的计算过程中,我们需要维护一个Hash表,Hash表的键为聚合计算的 Distinct修饰的 列,值为SQL的输出数据。

计算过程中,只需要根据每行输入数据计算出键,在 Hash 表中找到对应值即可。

 

<2> 伪代码描述

begin   calculate hash value on group by column(s)   check for a matching row in the hash table   if we do not find a match     insert a new row into the hash table end output all rows in the hash table

 

二、案例

测试SQL如下所示

SELECT  distinct departIdFROM  staff_

Oracle计划显示如下:

 

算法推演如下:

 

Distinct 语义优化

简单distinct语句优化

Distinct的语义是去除重复数据,通常需要获取到全部的数据才能去重,但是大量的数据可能内存承载不住,导致频繁的切外存操作。那么在分布式场景下有没有方案可以优化一下呢,答案是有的,可以针对普通的distinct语法转化成group by语法,通过集群分布式计算的能力,把数据先进行整理,最后输出。

 

如下面的案例所示

SELECT  distinct departIdFROM  staff_
可以优化成
SELECT  departIdFROM  staff_Group by    departId

 

这个两个SQL在结果上面是等价的。第二个SQL可以更加好的利用分布式的计算资源。

 

聚合函数distinct优化

通常情况下,DISTINCT的聚合函数(比如 select count(distinct a) from t)下推到数据源上面去进行优化操作。

如下面的案例所示

SELECT  count(distinct departId)FROM  staff_

 

结论

本文主要介绍了数据库关于Distinct功能常用的两种实现方式,Sort Distinct和Hash Distinct算法。并且描述了在分布式场景下Distinct优化的方式。

 

参考资料

  • http://www.sqlclauses.com/sql+distinct
  • https://www.pianshen.com/article/488778793/
  • http://www.cs.cmu.edu/afs/cs/user/dwoodruf/www/knw10b.pdf
  • 分享大数据行业的一些前沿技术和手撕一些开源库的源代码
    微信公众号名称:技术茶馆
    微信公众号ID    :    Night_ZW

 

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值