网站/小程序/APP个性化定制开发,二开,改版等服务,加扣:8582-36016

    今天无意中听到有同事在讨论,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进行去重时,性能相差不大

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


    评论 0

    暂无评论
    0
    0
    0
    立即
    投稿
    发表
    评论
    返回
    顶部