MySQL 中的 distinct 和 group by 的区别

news2025/2/26 6:24:46

目录

  • distinct用法
    • distinct多列去重
  • group by的使用
    • 单列去重
    • 多列去重
  • distinct和group by原理
  • 隐式排序
    • 基于上述原因,Mysql在8.0时,对此进行了优化更新:
  • 结论
    • 推荐group by的原因

在语义相同,有索引的情况下:group bydistinct都能使用索引,效率相同。
在语义相同,无索引的情况下:distinct效率高于group by。原因是distinctgroup by都会进行分组操作,但group by可能会进行排序,触发filesort,导致sql执行效率低下。

distinct用法

SELECT DISTINCT columns FROM table_name WHERE where_conditions;

在这里插入图片描述

DISTINCT 关键词用于返回唯一不同的值。放在查询语句中的第一个字段前使用,且作用于主句所有列。
如果列具有NULL值,并且对该列使用DISTINCT子句,MySQL将保留一个NULL值,并删除其它的NULL值,因为DISTINCT子句将所有NULL值视为相同的值。

distinct多列去重

distinct多列的去重,则是根据指定的去重的列信息来进行,即只有所有指定的列信息都相同,才会被认为是重复的信息。

在这里插入图片描述

group by的使用

对于基础去重来说,group by的使用和distinct类似:

单列去重

语法:

在这里插入图片描述

执行:

在这里插入图片描述

多列去重

语法:

SELECT columns FROM table_name WHERE where_conditions GROUP BY columns;

在这里插入图片描述

两者的语法区别在于,group by可以进行单列去重,group by的原理是先对结果进行分组排序,然后返回每组中的第一条数据。且是根据group by的后接字段进行去重的。

distinct和group by原理

在大多数例子中,DISTINCT可以被看作是特殊的GROUP BY,它们的实现都基于分组操作,且都可以通过松散索引扫描、紧凑索引扫描来实现。

DISTINCTGROUP BY都是可以使用索引进行扫描搜索的。例如以下两条sql(只单单看表格最后extra的内容),我们对这两条sql进行分析,可以看到,在extra中,这两条sql都使用了紧凑索引扫描Using index for group-by。

mysql> explain select int1_index from test_distinct_groupby group by int1_index;
+----+-------------+-----------------------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
| id | select_type | table                 | partitions | type  | possible_keys | key     | key_len | ref  | rows | filtered | Extra                    |
+----+-------------+-----------------------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
|  1 | SIMPLE      | test_distinct_groupby | NULL       | range | index_1       | index_1 | 5       | NULL |  955 |   100.00 | Using index for group-by |
+----+-------------+-----------------------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
1 row in set (0.05 sec)

mysql> explain select distinct int1_index from test_distinct_groupby;
+----+-------------+-----------------------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
| id | select_type | table                 | partitions | type  | possible_keys | key     | key_len | ref  | rows | filtered | Extra                    |
+----+-------------+-----------------------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
|  1 | SIMPLE      | test_distinct_groupby | NULL       | range | index_1       | index_1 | 5       | NULL |  955 |   100.00 | Using index for group-by |
+----+-------------+-----------------------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
1 row in set (0.05 sec)

但对于GROUP BY来说,在MYSQL8.0之前,GROUP BY默认会依据字段进行隐式排序。
可以看到,下面这条sql语句在使用了临时表的同时,还进行了filesort

mysql> explain select int6_bigger_random from test_distinct_groupby GROUP BY int6_bigger_random;
+----+-------------+-----------------------+------------+------+---------------+------+---------+------+-------+----------+---------------------------------+
| id | select_type | table                 | partitions | type | possible_keys | key  | key_len | ref  | rows  | filtered | Extra                           |
+----+-------------+-----------------------+------------+------+---------------+------+---------+------+-------+----------+---------------------------------+
|  1 | SIMPLE      | test_distinct_groupby | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 97402 |   100.00 | Using temporary; Using filesort |
+----+-------------+-----------------------+------------+------+---------------+------+---------+------+-------+----------+---------------------------------+
1 row in set (0.04 sec)

在这里插入图片描述

在这里插入图片描述

隐式排序

GROUP BY 默认隐式排序(指在 GROUP BY 列没有 ASC 或 DESC 指示符的情况下也会进行排序)。然而,GROUP BY进行显式或隐式排序已经过时(deprecated)了,要生成给定的排序顺序,请提供 ORDER BY 子句。

所以,在Mysql8.0之前,Group by会默认根据作用字段(Group by的后接字段)对结果进行排序。在能利用索引的情况下,Group by不需要额外进行排序操作;但当无法利用索引排序时,Mysql优化器就不得不选择通过使用临时表然后再排序的方式来实现GROUP BY了。

且当结果集的大小超出系统设置临时表大小时,Mysql会将临时表数据copy到磁盘上面再进行操作,语句的执行效率会变得极低。这也是Mysql选择将此操作(隐式排序)弃用的原因。

基于上述原因,Mysql在8.0时,对此进行了优化更新:

从前(Mysql5.7版本之前),Group by会根据确定的条件进行隐式排序。在mysql 8.0中,已经移除了这个功能,所以不再需要通过添加order by null 来禁止隐式排序了,但是,查询结果可能与以前的 MySQL 版本不同。要生成给定顺序的结果,请按通过ORDER BY指定需要进行排序的字段。

结论

  • 在语义相同,有索引的情况下:
    group bydistinct都能使用索引,效率相同。因为group bydistinct近乎等价,distinct可以被看做是特殊的group by

  • 在语义相同,无索引的情况下:
    distinct效率高于group by。原因是distinctgroup by都会进行分组操作,但group by在Mysql8.0之前会进行隐式排序,导致触发filesort,sql执行效率低下。

但从Mysql8.0开始,Mysql就删除了隐式排序,所以,此时在语义相同,无索引的情况下,group by和distinct的执行效率也是近乎等价的。

推荐group by的原因

  1. group by语义更为清晰
    2. group by可对数据进行更为复杂的一些处理

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

原文

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/501188.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

体验 Whisper

体验 Whisper 1. 什么是 Whisper2. Github 地址3. 创建虚拟环境4. 安装 ffmpeg5. 部署 Whisper6. 使用 Whisper 1. 什么是 Whisper Whisper 是一个通用的语音识别模型。它是在一个大型的不同音频数据集上训练出来的,也是一个多任务模型,可以进行多语言语…

MySQL笔记(一):设计范式、基础概念、数据库定义语言DDL

MySQL设计范式、基础概念、数据库定义语言DDL MySQL设计范式、基础概念、数据库定义语言DDL MySQL设计范式、基础概念、数据库定义语言DDL数据模型属性的特点 数据库的创建主键 数据库设计规范第一范式(1NF)第二范式(2NF)第三范式…

智能制造之路-从MES到MOM

当前,中国正在大力推动制造业的转型升级,实现由传统制造向智能制造转型。而制造信息化系统,作为支撑企业实现智能制造的一个关键因素,也正越来越多的吸引企业领导人的关注。 某大型制造业集团企业(下文简称M集团&…

【Java虚拟机】JVM日志分析和可视化工具实操

1.JVM垃圾GC日志参数配置实战 Java虚拟机中垃圾收集器在运行过程中输出的日志信息主要用于分析垃圾收集器的运行状态、优化垃圾收集器的工作效率以及定位垃圾收集相关的问题GC日志会包含以下内容 垃圾收集器的名称和版本信息。垃圾收集器的运行时间、开始时间和结束时间。垃圾…

【Fluent】利用TUI命令在保存或导出文件时,给文件名加上时间步长、流动时间、迭代步数等求解过程变量的自动编码

一、问题背景 在CSDN的一篇博客(从Fluent导出数据到txt文档)中,一位博主分享了一串导出求解数据的TUI命令。 file/export/ascii data%t.txt () yes h2s y-velocity x-velocity q no 当时我不知道里面的%t是啥意思,估计是跟时间…

JMeter介绍与安装教程

简介 JMeter是一款开源的负载测试工具,它可以用于测试Web应用程序、API、数据库、负载均衡器等。JMeter 是由 Apache 软件基金会开发的,其目标是提供一个高性能、易于使用的负载测试工具。 JMeter 具有以下特点: 可扩展性:JMet…

又开发好一个系统,详细记录软著申请过程

经过几个通宵达旦的撸代码之后,又开发好了一个系统,和以往一样,系统开发好了少不了申请软件著作权证书,兄弟们,软著申请搞起来啊。 在版权保护中心后台提交资料,没有账号的需要先注册一个账号。很重要的一步…

停车场收费系统

1.系统的开发工具 1.1 AppServe集成应用 Mysql:MySQL 是一款安全、跨平台、高效的,并与 PHP、Java 等主流编程语言紧密结合的数据库系统。该数据库系统是由瑞典的 MySQL AB 公司开发、发布并支持,由 MySQL 的初始开发人员 David Axmark 和 Mi…

【网络技术】什么是CIDR

序言 世界上最幸福的事之一,莫过于经过一番努力后,所有东西正慢慢变成你想要的样子。 文章标记颜色说明: 黄色:重要标题红色:用来标记结论绿色:用来标记一级论点蓝色:用来标记二级论点 1 基础介…

【设计模式】单例模式(懒汉和饿汉模式详解)

目录 1.设计模式是什么? 2.单例模式 1.概念: 2.如何设计一个单例 1.口头约定(不靠谱) 2.使用编程语言的特性来处理 3.使用"饿汉模式"设计单例 1.详细步骤 2.完整代码 4.使用"饿汉模式"设计单例 1.详…

php+vue在线课程教育学习考试系统864t7

运行环境:phpstudy/wamp/xammp等 开发语言:php 后端框架:Thinkphp5 前端框架:vue.js 服务器:apache 数据库:mysql 数据库工具:Navicat/phpmyadmin功能要求:可以实现首页、个人中心、学生管理、名…

嵌入式软考备考_7 系统开发过程和项目管理

系统开发过程和项目管理 开发模型 把开发过程分成一些阶段。 瀑布模型:SDLC。缺陷在于最开始需求要明确,但是开发周期很难不变动。 因此改进: 原型:一个demo。 快速原型模型:抛弃模型,一旦获取到了用户需…

unity 基本寻径

一、实现效果:敌人追逐玩家,自动躲避障碍物 二、游戏框架 Plane:平面,是玩家和敌人可以行走的区域 Player:玩家,可以在平面上移动,绕开障碍物 Enemy:敌人,可以追逐玩家…

红外遥控且自动避障的嵌入式智能小车系统

访问【WRITE-BUG数字空间】_[内附完整源码和文档] 本次实验使用树莓派作为开发平台,AlphaBot 作为开发载体,Python 作为开发语言,开发一种基于红外线遥控控制的、可自动避障的嵌入式智能小车系统。 智能系统中的嵌入式应用 实验目的 嵌入式…

MySQL双写缓冲区(Doublewrite Buffer)

本文已收录至Github,推荐阅读 👉 Java随想录 文章目录 摘要为什么需要Doublewrite BufferDoublewrite Buffer原理Doublewrite Buffer相关参数总结 摘要 InnoDB是MySQL中一种常用的事务性存储引擎,它具有很多优秀的特性。其中,Dou…

pip的常用操作命令

1. 忽略已安装的库(以llvmlite为例) pip install xxx --ignore-installed llvmlite 2. 错误 - AttributeError: int object has no attribute endswith 解决方案: 常见原因因为使用的pip为pip2,可以使用 pip -V 查看pip版本&a…

springboot+vue校园博客系统(源码+文档)

风定落花生,歌声逐流水,大家好我是风歌,混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的校园博客系统。项目源码以及部署相关请联系风歌,文末附上联系信息 。 💕💕作者:风歌&a…

AD 域环镜 本地管理员密码解决方案(LAPS)部署

前言: 我们知道window10装好后,默认本地管理员账号Administrator是关闭的,通过组策略启用本地管理员账号没有问题,具体方法在下面,但是由于微软《MS14-025:组策略首选项中的漏洞可能允许特权提升&#xff…

06-引入SpringSecurity 尚筹网

SpringSecurity 框架用法简介 用户登录系统时我们协助 SpringSecurity 把用户对应的角色、权限组装好,同时把各个资源所要求的权限信息设定好,剩下的“登录验证”、“权限验证”等等工作都交给SpringSecurity。 权限管理过程中的相关概念 主体 英文单…

【源码解析】Spring Cloud Gateway使用RedisRateLimiter实现限流

实现方案 在gateway项目中引入依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId> </dependency><dependency><groupId>org.springframework.boot</g…