`

关于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需要将col列中的全部内容都存储在一个内存中,可以理解为一个hash结构,key为col的值,最后计算hash结构中有多少个key即可得到结果。

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

 

而group by的方式是先将col排序。而数据库中的group一般使用sort的方法,即数据库会先对col进行排序。而排序的基本理论是,时间复杂为nlogn,空间为1.,然后只要单纯的计数就可以了。优点是空间复杂度小,缺点是要进行一次排序,执行时间会较长。

 

 

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

具体情况可参考如下法则

 

数据分布 去重方式 原因
离散 group distinct空间占用较大,在时间复杂度允许的情况下,group 可以发挥空间复杂度优势
集中 distinct distinct空间占用较小,可以发挥时间复杂度优势

 

两个极端:

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

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

 

 

当然,在group by时,某些数据库产品会根据数据列的情况智能地选择是使用排序去重还是hash去重,例如postgresql。当然,我们可以根据实际情况对执行计划进行人工的干预,而这不是这里要讨论的话题了。

 

 

2
0
分享到:
评论
1 楼 指尖残血 2016-03-24  
mark

相关推荐

    Mysql中distinct与group by的去重方面的区别

    distinct简单来说就是用来去重的,而group by的设计目的则是用来聚合统计的,两者在能够实现的功能上有些相同之处,但应该仔细区分。 单纯的去重操作使用distinct,速度是快于group by的。 distinct支持单列、多列的...

    MySQL去重该使用distinct还是group by?

    主要介绍了MySQL去重该使用distinct还是group by,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

    C# 实现Distinct将对象按条件去重

    平时,我们将c#中的Distinct大多用于对数组去重,一般数组为基础的数据类型,例如 int,string.也可以用于对象去重,我们看看C#对Distinct方法的定义: 有重载,第一个参数都加了this,是拓展方法,有关拓展方法,请...

    MongoDB教程之聚合(count、distinct和group)

    主要介绍了MongoDB教程之聚合,MongoDB除了基本的查询功能之外,还提供了强大的聚合功能,这里主要介绍count、distinct和group,需要的朋友可以参考下

    Distinct自定义去重

    今天遇到一个数组再分组的情况,思路是先找到分组的原则,之后再遍历一次得到分组的数据。 就是把所有重复的数据去掉,(分组依据) 重写了IEqualityComparer接口,并实现了它,但是有一点当明没有搞明白。...

    完美解决distinct中使用多个字段的方法

    完美解决distinct中使用多个字段的方法,完美解决distinct中使用多个字段的方法完美解决distinct中使用多个字段的方法完美解决distinct中使用多个字段的方法完美解决distinct中使用多个字段的方法

    MySQL中distinct与group by语句的一些比较及用法讲解

    在数据表中记录了用户验证时使用的书目,现在想取出所有书目,用DISTINCT和group by都取到了我想要的结果,但我发现返回结果排列不同,distinct会按数据存放顺序一条条显示,而group by会做个排序(一般是ASC)。...

    用C#实现对DataTable的JOIN,GROUP BY,FILTER,UNIONALL,DISTINCT

    用C#实现对DataTable的JOIN,GROUP BY,FILTER,UNIONALL,DISTINCT

    MySQL中Distinct和Group By语句的基本使用教程

    主要介绍了MySQL中Distinct和Group By语句的基本使用教程,这里主要是针对查询结果去重的用法,需要的朋友可以参考下

    MySQL中distinct与group by之间的性能进行比较

    主要针对MySQL中distinct与group by之间的性能进行比较,内容比较详细,很直观的能看出比较结果,感兴趣的小伙伴们可以参考一下

    利用Distinct()内置方法对List集合的去重问题详解

    说到对集合去重处理,第一时间想到的肯定是Linq的Distinct扩展方式,对于一般的值类型集合去重,很好处理,直接list.Distinct()即可。但是如果想要对一个引用类型的集合去重(属性值都相同就认为重复),就会发现,...

    django queryset 去重 .distinct()说明

    我就废话不多说了,大家还是直接看代码吧! contacts = ... return house.distinct() 合并出来的queryset,再去重。 补充知识:Python——深入理解urllib、urllib2及requests(requests不建议使用?)

    MySQL中distinct语句的基本原理及其与group by的比较

    DISTINCT 实际上和 GROUP BY 操作的实现非常相似,只不过是在 GROUP BY 之后的每组中只取出一条记录而已。所以,DISTINCT 的实现和 GROUP BY 的实现也基本差不多,没有太大的区别。同样可以通过松散索引扫描或者是...

    C# DataTable去重,根据列名去重保留其他列

    详细描述如何使用C# 去除DataTable中的重复列,根据列名去重保留其他列

    识破laravel+groupBy+count中那些隐藏着的秘密

    laravel框架中写统计用户的领取数量,打算用 groupBy + count来实现(去重+统计),加了groupBy之后再count,统计出来不的数量不对。查询资料+反复测试终于得到了解决方案。 错误的查询语句 :cross_mark: Model::...

    MySQL中使用去重distinct方法的示例详解

    含义:distinct用来查询不重复记录的条数,即distinct来返回不重复字段的条数(count(distinct id)),其原因是distinct只能返回他的目标字段,而无法返回其他字段 用法注意: 1.distinct【查询字段】,必须放在要查询...

Global site tag (gtag.js) - Google Analytics