distinct和group by去重逻辑浅析

在数据库操作中,我们常常遇到需要将数据去重计数的工作。例如:

表A,列col
A
C
A
B
C
D
A
B

结果就是一共出现4个不同的字母A、B、C、D

即结果为4

大体上我们可以选择count(distinct col)的方法和group+count的方法。

分别为:

select count(distinct col) from A;

select count(1) from (select 1 from A group by col) alias;

两中方法实现有什么不同呢?

其实上述两中方法分别是在运算存储上的权衡。

distinct

distinct需要将col列中的全部内容都存储在一个内存中,可以理解为一个hash结构,keycol

值,最后计算hash结构中有多少个key即可得到结果。

很明显,需要将所有不同的值都存起来。内存消耗可能较大。

group by

group by的方式是先将col排序。而数据库中的group一般使用sort的方法,即数据库会先对col

行排序。而排序的基本理论是,时间复杂为nlogn,空间为1.,然后只要单纯的计数就可以了。优点是

空间复杂度小,缺点是要进行一次排序,执行时间会较长。

如果该我们仅仅想去重,而不需要排序,可以在后面加入order by null子句后,MySQL不会创建

sort index进行排序(内存排序非常快,优化效果并不明显,并且这个阶段只是每个数据块的排序)。

总结

两中方法各有优劣,在使用的时候,我们需要根据实际情况进行取舍。

具体情况可参考如下法则:
在这里插入图片描述
两个极端:

  1. 数据列的所有数据都一样,即去重计数的结果为1时,用distinct最佳。

  2. 如果数据列唯一,没有相同数值,用group最好。

当然,在group by时,某些数据库产品会根据数据列的情况智能地选择是使用排序去重还是hash

重,例如postgresql。当然,我们可以根据实际情况对执行计划进行人工的干预,而这不是这里要讨论

的话题了。

参考文献:
group by与distinct效率分析及优化措施

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值