MySQL三种去重方式比较

引言:

在MySQL数据库中,数据去重是一项常见的操作。通过去除重复的数据,可以提高查询效率和数据的整洁度。本文将比较MySQL中常用的三种去重方式,包括使用DISTINCT关键字、使用GROUP BY子句和使用窗口函数ROW_NUMBER(),以帮助读者选择最适合自己的去重方法。

三种去重方法介绍:

  1. 使用DISTINCT关键字:
    DISTINCT关键字是MySQL提供的一种去重方式。它可以用在SELECT语句中,去除查询结果中的重复记录。使用DISTINCT关键字的语法简单,只需要在SELECT关键字之后加上DISTINCT即可,这种方式适用于对单个列或多个列进行去重的情况。

    SELECT DISTINCT column1, column2 FROM table_name
    
  • 优点:

     1.语法简单明了,容易理解和使用。
     2.可以同时对多个列进行去重,灵活性较好。
    
  • 缺点:

     1.DISTINCT关键字只能按照select的列进行去重,如果需要查询其他不用去重的列,需要额外处理。
    
  1. 使用GROUP BY子句:
    GROUP BY子句是另一种常用的去重方式。它将查询结果按照指定的列进行分组,并对每个分组进行聚合操作。通过使用GROUP BY子句,我们可以将重复的记录分组合并,达到去重的效果。
  • 优点:

     1.可以对多个列进行分组和进行组内聚合操作,提供更灵活的功能。
    
  • 缺点:

     1.GROUP BY子句的语法比较复杂,学习和理解成本较高。
     2.如果需要返回不在group by里面的字段,需要设置sql_model参数。
     3.需要注意使用聚合函数处理分组后的数据。
    
  1. 使用窗口函数ROW_NUMBER():
    ROW_NUMBER()函数是SQL中的一个窗口函数,用于为每一行数据分配一个唯一的序列号,当根据需要的字段排序后,取序列号为1的数据,即可完成去重操作。

    -- example
    SELECT *
    	FROM (
    	   SELECT *, ROW_NUMBER() OVER (PARTITION BY column1, column2, ... ORDER BY column1, column2, ...) AS rn
    	   FROM table
    	) AS subquery
    WHERE rn = 1;
    
    
  • 优点:

     1.ROW_NUMBER()函数是SQL标准中提供的窗口函数之一,使用广泛且简单易懂。
     2.可以根据需要按照分组后的结果的某列或者某几列再进行组内分组排序,然后通过将ROW_NUMBER()结果为1的行保留下来,可以实现对重复数据的去重操作。
     3.通过在ORDER BY子句中指定不同的列和排序顺序,可以灵活地根据具体需求进行去重和排序。
    
  • 缺点:

     1.只能去重连续行:ROW_NUMBER()函数只能对连续的行(分组后的组内)进行排序和排除,如果要处理非连续(分组后的非组内)的重复行,需要采用其他的方法。
     3.语法复杂:语法中涉及到嵌套查询和窗口函数的使用,相对于其他简单的去重方法,可能稍显复杂一些。
    

效率比较:

首先建立一个测试表,制造一些简单的测试数据,数据量大概在200w+,如果数据量少很难观察到效果:

-- test.out_order_item definition
CREATE TABLE `out_order_item` (
  `id` int NOT NULL AUTO_INCREMENT,
  `sale_order_id` int NOT NULL DEFAULT 0,
  PRIMARY KEY (`id`)
);
  • 没有索引的情况:

    -- group by方式
    select
    	sale_order_id
    from
    	test.out_order_item
    group by
    	sale_order_id
    limit 200;
    -- 运行10次,2.5s左右
    -- limit数量不受影响
    
    
    -- distinct方式
    select
    	distinct sale_order_id
    from
    	test.out_order_item
    limit 200;
    -- 运行10次,5ms左右
    -- limit 20000, 40ms左右
    -- limit 2000000, 2.5s左右
    
    -- row_number方式
    select
    	sale_order_id
    from
    	(select
    		row_number() over(partition by sale_order_id) rn,
    		sale_order_id
    	from test.out_order_item) a
    where
    	rn = 1
    limit 200;
    -- 运行10次,5.5s左右
    -- limit数量不受影响
    
  • 有索引的情况:

    先给表字段sale_order_id添加索引

    CREATE INDEX sale_order_id_IDX USING BTREE ON test.out_order_item (sale_order_id);
    
    -- group by方式
    select
    	sale_order_id
    from
    	test.out_order_item
    group by
    	sale_order_id
    limit 200;
    -- 运行10次,1ms左右
    -- limit 20000,40ms左右
    -- limit 2000000,1.2s左右
    
    
    -- distinct方式
    select
    	distinct sale_order_id
    from
    	test.out_order_item
    limit 200;
    -- 运行10次,1ms左右
    -- limit 20000, 40ms左右
    -- limit 2000000, 1.5s左右
    
    -- row_number方式
    select
    	sale_order_id
    from
    	(select
    		row_number() over(partition by sale_order_id) rn,
    		sale_order_id
    	from test.out_order_item) a
    where
    	rn = 1
    limit 200;
    -- 运行10次,5.5s左右
    -- limit数量不受影响
    

结论:

从上面的结果的执行时间可以看出,三种去重方法可以适用于不同的场景,而且其效率也不相同。

  • 适用场景:

    1. distinct:简单的字段去重,不需要其他操作;
    2. group by:需要进行额外的聚合处理;
    3. row_number():想要返回非去重的其他列;
  • 效率影响:

    • 无索引情况
      1. distinct:取决于返回结果集的大小,数量远小于表数量时性能最好;
      2. group by:不受结果集影响,性能中等;
      3. row_number():不受结果集影响,性能最差;
    • 有索引情况
      1. distinct:取决于返回结果集的大小,结果集少时与group by相差不大;
      2. group by:取决于返回结果集的大小,结果集大时,比distinct性能好;
      3. row_number():不受结果集影响,性能最差;

以上是简单的从现象得出的结论,有兴趣研究其原因的小伙伴可以通过explain关键字看看执行计划,分析为何出现这种情况,这里就先不展开具体分析。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

TCP和IP数据包结构

一、问题引入 一般我们在谈上网速度的时候,专业上用带宽来描述,其实无论说网速或者带宽都是不准确的,呵呵。比如:1兆,512K……有些在学校的学生,也许会有疑问,明明我的业务是1M,为…

某yi逆向sign值

1. 定位 url: aHR0cHM6Ly93d3cuaXFpeWkuY29tL3ZfMTlycjRyZ3AxZy5odG1s打开网址,找到sign值所在位置 应该是32位大写md5加密,可以看到console中加载出来很多东西,往下翻到base_info所在位置 点进去main.js,打上断点 2. 调试 刷…

项目基础知识

1.JDBC编程和MySQL数据库 数据库的连接(以前写qq项目时的代码) package com.wu.Util; import java.sql.*; public class JDBCUtil {private static JDBCUtil jdbcUtil null;private JDBCUtil() {}public static JDBCUtil getJdbcUtil() {if (jdbcUtil…

基于Echarts进行图表组件的封装

什么是Echarts 是一个使用js实现的开源可视库,提供了多种图表,但是当我们在项目中进行使用的时候可能就是需要进行一系列的相关配置如: 标题,类型,x轴,y轴等,当我们使用较为频繁的时候就容易导…

昇思25天学习打卡营第16天 | DCGAN生成漫画头像

这两天把minspore配置到我的电脑上了,然后运行就没什么问题了✨😊 今天学这个DCGAN生成漫画头像,我超级感兴趣的嘞🦄🥰 GAN基础原理 这部分原理介绍参考GAN图像生成。 DCGAN原理 DCGAN(深度卷积对抗生成…

一本超简单能用Python实现办公自动化的神书!让我轻松摆脱办公烦恼!

《超简单:用Python让Excel飞起来》 这本书旨在通过Python与Excel的“强强联手”,为办公人员提供一套高效的数据处理方案。书中还介绍了如何在Excel中调用Python代码,进一步拓宽了办公自动化的应用范围。 全书共9章。第1~3章主要讲解Python编…

【数据结构】06.栈队列

一、栈 1.1栈的概念及结构 栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。 压栈&#…

JAVA 对象存储OSS工具类(腾讯云)

对象存储OSS工具类 import com.qcloud.cos.COSClient; import com.qcloud.cos.ClientConfig; import com.qcloud.cos.auth.BasicCOSCredentials; import com.qcloud.cos.auth.COSCredentials; import com.qcloud.cos.model.ObjectMetadata; import com.qcloud.cos.model.PutObj…

洗地机品牌哪个最好用?硬核推荐五大实力爆款洗地机

在这个忙碌的时代,家就是我们放松的港湾,但要保持它的清洁与舒适常常很不容易。每天拖着疲惫的身体回家,还要面对地板上那些难缠的灰尘、污渍,真是非常让人头疼。不过,洗地机的出现就像是给家务清洁装上了智能引擎&…

idea中maven全局配置

配置了就不需要每次创建项目都来设置maven仓库了。 1.先把项目全关了 2. 进入全局设置 3.设置maven的仓库就可以了

一篇文章带你完全理解C语言数组

文章目录 1.一维数组的创建和初始化数组的创建1.2数组的初始化1.3 一维数组的使用1.4一维数组在内存中的存储 2.二维数组的创建和初始化2.1二维数组的创建2.2 二维数组的初始化2.3 二维数组的使用2.4 二维数组在内存中的存储 3.数组越界4.数组作为函数参数4.1 冒泡排序函数的错…

从零开始开发美颜SDK:打造属于平台的主播美颜工具

本篇文章,小编将从零开始,介绍如何打造一款属于平台的主播美颜工具。 一、需求分析 首先,明确开发美颜SDK的需求是至关重要的。当前市场上,美颜工具的功能主要包括: 1.实时美颜:磨皮、美白、瘦脸等基础功…

Static关键字的用法详解

Static关键字的用法详解 1、Static修饰内部类2、Static修饰方法3、Static修饰变量4、Static修饰代码块5、总结 💖The Begin💖点点关注,收藏不迷路💖 在Java编程语言中,static是一个关键字,它可以用于多种上…

项目机会:4万平:智能仓,AGV,穿梭车,AMR,WMS,提升机,机器人……

导语 大家好,我是社长,老K。专注分享智能制造和智能仓储物流等内容。 如下为近期国内智能仓储物流相关项目的公开信息线索,这些项目具体信息会发布到知识星球,请感兴趣的球友先人一步到知识星球【智能仓储物流技术研习社】自行下载…

时钟系统框图(时钟树)解析

时钟系统框图(时钟树)解析 文章目录 时钟系统框图(时钟树)解析1、时钟树2、 4个时钟源:$HSI、HSE、LSI、LSE$3、PLL锁相环倍频输出4、系统时钟的来源5、Enable CSS(时钟监视系统)6、几个重要的时…

微信开发者工具使用

1.下载微信开发者工具 https://developers.weixin.qq.com/miniprogram/dev/devtools/stable.html 2.下载小程序项目代码 3.用微信开发者工具导入项目代码 4.npm安装依赖 5.构建 6.修改测试环境 7.清除缓存 观察切换test后,登录时是否test字样提醒,若…

使用Python+OpenCV实现姿态估计--20240705

姿态估计使用Opencv+Mediapipe来时实现 什么是Mediapipe? Mediapipe是主要用于构建多模式音频,视频或任何时间序列数据的框架。借助MediaPipe框架,可以构建令人印象深刻的ML管道,例如TensorFlow,TFLite等推理模型以及媒体处理功能。 安装命令: pip install mediapipe如果…

大模型提示词工程和落地思考

本文是一篇内部的个人分享(已无敏感信息) ,目的是增加产品、开发同学对 LLM 的理解,以降低沟通中的阻力,更好推进落地。 以下经脱敏后的原文: 大模型并不神奇 很多人听到’大模型’这个词可能会觉得很神秘&#xff…

centos7固定ip

1.查看虚拟网络配置 2.修改网卡配置文件 [jiajinglocalhost ~]$ su - Password: Last login: Thu Jul 4 19:06:16 PDT 2024 on pts/0 [rootlocalhost ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens33 TYPE"Ethernet" PROXY_METHOD"none" BROWSER_ON…

倘若你的的B端系统如此漂亮,还担心拿不出手吗,尤其是面对客户

如果你的B端系统设计如此漂亮,那么通常来说,你不太需要担心在客户那里拿不出手。一个漂亮和易用的设计可以提升用户体验,增加客户对系统的满意度。 然而,还是有一些因素需要考虑,以确保你的B端系统在客户那里能够得到良…