MySQL去重中distinct和group by的区别浅析

 更新时间:2022年11月09日 11:10:15   作者:小黑孩666  
今天无意中听到有同事在讨论,distinct和group by有什么区别,下面这篇文章主要给大家介绍了关于MySQL去重中distinct和group by区别的相关资料,需要的朋友可以参考下

今天在写业务需要对数据库重复字段进行去重时,因为是去重,首先想到的是distinct关键字。于是一小时过去了。。。。(菜鸟一个,大家轻点骂)

我把问题的过程用sql语句演示给大家演示一下

首先我使用的是mybatis-plus,代码如下

QueryWrapper<ProjectCompany> wrapper = new QueryWrapper<>();
        wrapper.select("DISTINCT project_id,company_id,company_name,is_delete").eq("project_id",projectId).eq("is_delete","0");

即     "DISTINCT project_id,company_id,company_name,is_delete" 

查出的结果

id=null。这是我不希望看到的。没有id的话,下面的业务就不好走了。

于是我在distinct后面加上了id,distinct查出来的数据就是全部数据了,相当于distinct没起作用。冥思苦想一小时。。。。

后来想到了group by分组,于是用了一下

LambdaQueryWrapper<ProjectCompany> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProjectCompany::getProjectId,projectId).eq(ProjectCompany::getIsDelete,"0").groupBy(ProjectCompany::getProjectId);

发现查出来的数据也进行去重了,id也有值

所以就很好奇 distinct和group by有啥区别,大概总结以下几点:

distinct适合查单个字段去重,支持单列、多列的去重方式。 单列去重的方式简明易懂,即相同值只保留1个。 
多列的去重则是根据指定的去重的列信息来进行,即只有所有指定的列信息都相同,才会被认为是重复的信息。

而 group by 可以针对要查询的全部字段中的部分字段去重,它的作用主要是:获取数据表中以分组字段为依据的其他统计数据。

补充:MySQL中distinct和group by去重性能对比

前言

  • MySQL:5.7.17
  • 存储引擎:InnoDB
  • 实验目的:本文主要测试在某字段有无索引、各种不同值个数情况下,记录对此字段其使用DISTINCT/GROUP BY去重的查询语句执行时间,对比两者在不同场景下的去重性能,实验过程中关闭MySQL查询缓存。
  • 实验表格:
表名记录数查询字段有无索引查询字段不同值个数DISTINCTGROUP BY
tab_1100000N3  
tab_2100000Y3  
tab_3100000N10000  
tab_4100000Y10000  

实验过程

1)创建测试表

表创建语句:

DROP TABLE IF EXISTS `tab_1`;
CREATE TABLE `tab_1` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `value` int(10) unsigned NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

DROP TABLE IF EXISTS `tab_2`;
CREATE TABLE `tab_2` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `value` int(10) unsigned NOT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_value` (`value`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

DROP TABLE IF EXISTS `tab_3`;
CREATE TABLE `tab_3` LIKE `tab_1`;

DROP TABLE IF EXISTS `tab_4`;
CREATE TABLE `tab_4` LIKE `tab_2`;

2)生成测试数据

表数据插入过程:

DROP PROCEDURE IF EXISTS generateRandomData;
delimiter $$
-- tblName为插入表,field为插入字段,num为插入字段值上限,count为插入的记录数
CREATE PROCEDURE generateRandomData(IN tblName VARCHAR(30),IN field VARCHAR(30),IN num INT UNSIGNED,IN count INT UNSIGNED)
BEGIN
	-- 声明循环变量
	DECLARE i INT UNSIGNED DEFAULT 1;
	-- 循环插入随机整数1~num,共插入count条数据
	w1:WHILE i<=count DO
		set i=i+1;
		set @val = FLOOR(RAND()*num+1);
		set @statement = CONCAT('INSERT INTO ',tblName,'(`',field,'`) VALUES(',@val,')');
		PREPARE stmt FROM @statement;
		EXECUTE stmt;
	END WHILE w1;
END $$
delimiter ;

调用过程随机生成测试数据:

call generateRandomData('tab_1','value',3,100000);
INSERT INTO tab_2 SELECT * FROM tab_1;

call generateRandomData('tab_3','value',10000,100000);
INSERT INTO tab_4 SELECT * FROM tab_3;

3)执行查询语句,记录执行时间

查询语句及对应执行时间如下:

SELECT DISTINCT(`value`) FROM tab_1;
SELECT `value` FROM tab_1 GROUP BY `value`;

SELECT DISTINCT(`value`) FROM tab_2;
SELECT `value` FROM tab_2 GROUP BY `value`;

SELECT DISTINCT(`value`) FROM tab_3;
SELECT `value` FROM tab_3 GROUP BY `value`;

SELECT DISTINCT(`value`) FROM tab_4;
SELECT `value` FROM tab_4 GROUP BY `value`;

4)实验结果

表名记录数查询字段有无索引查询字段不同值个数DISTINCTGROUP BY
tab_1100000N30.058s0.059s
tab_2100000Y30.030s0.027s
tab_3100000N100000.072s0.073s
tab_4100000Y100000.047s0.049s

实验结论

MySQL 5.7.17中使用distinct和group by进行去重时,性能相差不大

实验过程及结论,如有不足之处,欢迎指正,此实验结论仅供参考。

总结

到此这篇关于MySQL去重中distinct和group by区别浅析的文章就介绍到这了,更多相关MySQL去重distinct和group by区别内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MySQL半同步复制原理配置与介绍详解

    MySQL半同步复制原理配置与介绍详解

    这篇文章主要介绍了MySQL半同步复制原理配置与介绍详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-01-01
  • mysql 数据库备份的多种实现方式总结

    mysql 数据库备份的多种实现方式总结

    这篇文章主要介绍了mysql 数据库备份的多种实现方式,总结分析了MySQL数据库备份的常见语句、使用方法及操作注意事项,需要的朋友可以参考下
    2020-02-02
  • MySQL从命令行导入SQL脚本时出现中文乱码的解决方法

    MySQL从命令行导入SQL脚本时出现中文乱码的解决方法

    这篇文章主要介绍了MySQL从命令行导入SQL脚本时出现中文乱码的解决方法,分析了中文乱码出现的原因并给出了两种解决方法供大家参考,需要的朋友可以参考下
    2016-09-09
  • 详解MySQL连接挂死的原因

    详解MySQL连接挂死的原因

    本次分享的是一次关于 MySQL 高可用问题的定位过程,其中曲折颇多但问题本身却比较有些代表性,遂将其记录以供参考。
    2021-05-05
  • MySql安装与使用图文教程【推荐】

    MySql安装与使用图文教程【推荐】

    mysql是一种关联数据库管理系统,在程序开发中应用非常广泛,下面通过本文给大家介绍mysql安装与使用教程,感兴趣的朋友一起学习吧
    2016-05-05
  • MySQL语句之MD5()的使用方式

    MySQL语句之MD5()的使用方式

    这篇文章主要介绍了MySQL语句之MD5()的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-04-04
  • MySQL 数据类型和建库策略

    MySQL 数据类型和建库策略

    无论是在小得可怜的免费数据库空间或是大型电子商务网站,合理的设计表结构、充分利用空间是十分必要的。这就要求我们对数据库系统的常用数据类型有充分的认识。
    2008-12-12
  • MySql存储过程异常处理示例代码分享

    MySql存储过程异常处理示例代码分享

    在网上查了好多资料,发现关于mysql的异常处理资料都是一些错误号列表,对于平时运行中,我们可能更多的希望能够记录准确的错误消息到日志中
    2012-06-06
  • MySQL由浅入深掌握连接查询

    MySQL由浅入深掌握连接查询

    连接查询是关系数据库中最主要的查询,主要包括内连接、外连接和交叉连接等。通过连接运算符可以实现多个表查询。连接是关系数据库模型的主要特点,也是它区别于其它类型数据库管理系统的一个标志
    2022-03-03
  • MySql状态查看方法 MySql如何查看连接数和状态?

    MySql状态查看方法 MySql如何查看连接数和状态?

    如果是root帐号,你能看到所有用户的当前连接。如果是其它普通帐号,只能看到自己占用的连接
    2012-11-11

最新评论