MySQL中 distinct 和 group by 的区别及效率问题

简介:MySQL中 distinct 和 group by的区别,distinct和group by哪个效率更高

在MySQL中distinct的作用是对单个字段或多个字段的查询结果去重操作,而group by是对单个或多个字段的查询结果进行分组分组操作。除了主要作用不同之外,他们之前还有其他什么不同呢?

在具体讲解之前,我们需要创建测试表

CREATE TABLE `test` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `a` int(11) NOT NULL DEFAULT '0' COMMENT '测试字段a',
  `b` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '测试字段b',
  `c` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '测试字段c',
  PRIMARY KEY (`id`),
  KEY `a_index` (`a`),
  KEY `b_index` (`b`),
  KEY `c_index` (`c`)
) ENGINE=InnoDB AUTO_INCREMENT=4267 DEFAULT CHARSET=utf8 COMMENT='测试表'

我们可以添加一些测试数据,将下面的SQL重复执行100遍

insert into test(a,b,c) values (1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),(6,6,6),(7,7,7),(8,8,8),(9,9,9),(11,11,11);

1. distinct的使用

distinct关键词用于返回唯一不同的值,包括NULL值。

select distinct 地段名 from 表名称;

但是大多数情况和【group by】一样都是配合聚合函数使用。

1.1 单个字段进行去重

例如:查询某日订单支付的用户数

1.2 多个字段去重操作

2. group by的使用

根据一个或多个字段分组查询,一般搭配聚合函数使用。基本使用方式如下:

SELECT columns FROM 表名称 where_conditions GROUP BY 分组的字段名;

2.1 单个字段分组查询

例如:统计某日不同渠道支付订单数

source:是渠道的标识

2.2 多字段分组查询

在用法上【group by】基本与【distinct】相同,唯一不同的是【group by】在WHERE条件之后,【distinct】在返回的字段中使用。

3. 使用Explain分析两者的不同

如果大家不了解Explain的可以看看我之前的文章MySQL中SQL性能分享-explain详解】。我们先来看看【distinct】的分析结果吧

通过Extra的分析结果可以看出:SQL执行使用了索引,【distinct】没有结合聚合函数使用时,会触发临时表。

接下来我们再来看看【group by】的分析结果:

此时我们发现【group by】永远都会触发临时表。其时这是【group by】触发了隐式排序的功能。不过在MySQL8之后【group by】不会触发隐式排序,在MySQL8以后如果需要自定义排序可以通过【order by】指定排序方式

总结:

在语义相同,有索引的情况下:group by和distinct都能使用索引,效率相同。

在语义相同,无索引的情况下:【distinct】效率高于【group by】。【distinct】和【group by】都会进行分组操作,但是group by可能会进行隐式排序,导致SQL执行效率低下。但从Mysql8.0开始,Mysql就删除了隐式排序,所以,此时在语义相同,无索引的情况下,【group by】和【distinct】的执行效率也是近乎等价的。

相比于【distinct】来说,【group by】的语义明确。且由于【distinct】关键字会对所有字段生效,在进行复合业务处理时,【group by】的使用灵活性更高,【group by】能根据分组情况,对数据进行更为复杂的处理,例如通过having对数据进行过滤,或通过聚合函数对数据进行运算。因此我推荐大家使用【group by】来操作统计。

有遗漏或者不对的可以在我的公众号留言哦

编程经验共享公众号二维码

编程经验共享公众号二维码
更多内容关注公众号
Copyright © 2021 编程经验共享 赣ICP备2021010401号-1