目录

概述

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 departId
FROM
  staff_
ORDER BY 
  departId

Oracle计划显示如下:

mysql中distinct报语法错误_分布式数据库

 

算法推演如下:

mysql中distinct报语法错误_mysql中distinct报语法错误_02

mysql中distinct报语法错误_mysql中distinct报语法错误_03

mysql中distinct报语法错误_mysql中distinct报语法错误_04

mysql中distinct报语法错误_大数据_05

mysql中distinct报语法错误_数据库_06

mysql中distinct报语法错误_分布式数据库_07

mysql中distinct报语法错误_分布式数据库_08

 

 

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 departId
FROM
  staff_

Oracle计划显示如下:

mysql中distinct报语法错误_分布式数据库_09

 

算法推演如下:

mysql中distinct报语法错误_数据_10

mysql中distinct报语法错误_分布式数据库_11

mysql中distinct报语法错误_分布式数据库_12

mysql中distinct报语法错误_mysql中distinct报语法错误_13

mysql中distinct报语法错误_分布式数据库_14

mysql中distinct报语法错误_大数据_15

 

Distinct 语义优化

简单distinct语句优化

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

 

如下面的案例所示

SELECT
  distinct departId
FROM
  staff_
SELECT
  departId
FROM
  staff_
Group by
    departId

 

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

mysql中distinct报语法错误_数据库_16

 

聚合函数distinct优化

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

如下面的案例所示

SELECT
  count(distinct departId)
FROM
  staff_

mysql中distinct报语法错误_mysql中distinct报语法错误_17

 

结论

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