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

 更新时间:2023年03月03日 10:04:26   作者:菜鸟小杰子  
distinct 与 group by均可用于去重,下面这篇文章主要给大家介绍了关于MySQL中distinct和group by去重效率区别的相关资料,文中介绍的非常详细,需要的朋友可以参考下

一、distinct

distinct的作用

在mysql中,distinct关键字的主要作用就是对数据库表中一个或者多个字段重复的数据进行过滤,只返回其中的一条数据给用户,distinct只可以在select中使用

distinct的原理

distinct进行去重的主要原理是通过先对要进行去重的数据进行分组操作,然后从分组后的每组数据中去一条返回给客户端,在这个分组的过程可能会出现两种不同的情况:

distinct 依赖的字段全部包含索引:

该情况mysql直接通过操作索引对满足条件的数据进行分组,然后从分组后的每组数据中去一条数据。

distinct 依赖的字段未全部包含索引:

该情况由于索引不能满足整个去重分组的过程,所以需要用到临时表,mysql首先需要将满足条件的数据放到临时表中,然后在临时表中对该部分数据进行分组,然后从临时表中每个分组的数据中去一条数据,在临时表中进行分组的过程中不会对数据进行排序。

distinct的语法:

select distinct expression[,expression…] from tables [where conditions];

在使用distinct的过程中主要注意一下几点:

在对字段进行去重的时候,要保证distinct在所有字段的最前面

如果distinct关键字后面有多个字段时,则会对多个字段进行组合去重,只有多个字段组合起来的值是相等的才会被去重

二、group by

groupby在Mysql8.0之前会进行隐式排序,导致触发filesort,sql执行效率低下,Mysql8.0开始,Mysql就删除了隐式排序

隐式排序

对于隐式排序,我们可以参考Mysql官方的解释:

MySQL :: MySQL 5.7 Reference Manual :: 8.2.1.14 ORDER BY Optimization

GROUP BY implicitly sorts by default (that is, in the absence of ASC
or DESC designators for GROUP BY columns). However, relying on
implicit GROUP BY sorting (that is, sorting in the absence of ASC or
DESC designators) or explicit sorting for GROUP BY (that is, by using
explicit ASC or DESC designators for GROUP BY columns) is deprecated.
To produce a given sort order, provide an ORDER BY clause.

大致解释一下:

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

所以,在Mysql8.0之前,Group by会默认根据作用字段(Groupby的后接字段)对结果进行排序。在能利用索引的情况下,Group by不需要额外进行排序操作;但当无法利用索引排序时,Mysql优化器就不得不选择通过使用临时表然后再排序的方式来实现GROUPBY了。且当结果集的大小超出系统设置临时表大小时,Mysql会将临时表数据copy到磁盘上面再进行操作,语句的执行效率会变得极低。这也是Mysql选择将此操作(隐式排序)弃用的原因。

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

MySQL :: MySQL 8.0 Reference Manual :: 8.2.1.16 ORDER BY Optimization

Previously (MySQL 5.7 and lower), GROUP BY sorted implicitly under
certain conditions. In MySQL 8.0, that no longer occurs, so specifying
ORDER BY NULL at the end to suppress implicit sorting (as was done
previously) is no longer necessary. However, query results may differ
from previous MySQL versions. To produce a given sort order, provide
an ORDER BY claus

大致解释一下:

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

三、distinct 和 group by 比较

在语义相同,有索引的情况下:

group by和distinct都能使用索引,效率相同。因为groupby和distinct近乎等价,distinct可以被看做是特殊的group by。

在语义相同,无索引的情况下:

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

推荐group by的原因:

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

distinct 主要是对数据两两进行比较,需要遍历整个表

group by 是在查询时先把数据按照分组字段分组出来再查询,当数据量较大时,group by 速度要优于 distinct

总结

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

相关文章

  • MLSQL Stack如何让流调试更加简单详解

    MLSQL Stack如何让流调试更加简单详解

    这篇文章主要给大家介绍了关于MLSQL Stack如何让流调试更加简单的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用MLSQL具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-06-06
  • MySQL INSERT INTO SELECT时自增Id不连续问题及解决

    MySQL INSERT INTO SELECT时自增Id不连续问题及解决

    这篇文章主要介绍了INSERT INTO SELECT时自增Id不连续问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • MySQL InnoDB 事务锁源码分析

    MySQL InnoDB 事务锁源码分析

    InnoDB 事务锁,事务锁实现起来的代码却是又臭又硬的好大一坨,各种细节,今天小编在这里整理一个源码阅读笔记,把那一坨加锁相关的代码提炼出来,感兴趣的小伙伴别忘记收藏奥
    2021-09-09
  • MySQL的事件调度器使用介绍

    MySQL的事件调度器使用介绍

    这篇文章主要介绍了MySQL的事件调度器使用介绍,本文讲解了事件调度器的开启、创建、修改、删除等操作的使用实例,需要的朋友可以参考下
    2015-06-06
  • mysql 的replace into实例详解

    mysql 的replace into实例详解

    这篇文章主要介绍了mysql 的replace into实例详解的相关资料,需要的朋友可以参考下
    2017-06-06
  • M1芯片安装mysql8.0数据库的实现步骤(图文)

    M1芯片安装mysql8.0数据库的实现步骤(图文)

    这篇文章主要介绍了M1芯片安装mysql8.0数据库的实现实现步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-02-02
  • MySQL优化教程之慢查询日志实践

    MySQL优化教程之慢查询日志实践

    在MySQL中慢查询日志主要用来记录响应时间超过阈值的SQL,下面这篇文章主要给大家介绍了关于MySQL优化教程之慢查询日志的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-06-06
  • MySQL系统库之information_schema的实现

    MySQL系统库之information_schema的实现

    information_schema用于存储数据库元数据,本文主要介绍了MySQL系统库之information_schema的实现,具有一定的参考价值,感兴趣的可以了解一下
    2023-11-11
  • 浅析MySQL显式类型转换

    浅析MySQL显式类型转换

    这篇文章主要介绍了MySQL显式类型转换的基础知识,通过实例给出了分析结果,一起学习下吧。
    2017-12-12
  • MySQL数据库操作DML 插入数据,删除数据,更新数据

    MySQL数据库操作DML 插入数据,删除数据,更新数据

    这篇文章主要介绍了MySQL数据库操作DML插入数据,删除数据,更新数据,DML是指数据操作语言,英文全称是Data Manipulation Language,用来对数据库中表的数据记录进行更新
    2022-07-07

最新评论