MySQL中的数据去重,该用DISTINCT还是GROUP BY?
在日常工作中,中重该数据库查询操作无处不在,据去而处理数据中的中重该重复项与分组汇总是非常常见的需求。
MySQL 提供了两种常见的据去方式来管理和检索唯一值:SELECT DISTINCT 和 GROUP BY。这两者虽然在生成输出上可能相似,中重该但用途与性能各有不同,据去使用场景也有所区分。中重该

这篇文章带大家将从功能、据去性能以及实际应用等方面详细介绍 DISTINCT 和 GROUP BY 的中重该差异,并结合具体的据去示例数据来理解其使用场景。
SELECT DISTINCT
DISTINCT 是中重该一个用于去重的关键字。SELECT DISTINCT 语句用于从结果集中删除重复行,据去只返回唯一值。中重该因此,据去在需要仅获取数据的中重该唯一部分时,DISTINCT 是一种简单高效的方式。
基本语法
复制SELECT DISTINCT column1, column2 FROM table_name;1.2.参数说明:
column1, column2:要检索的字段名。table_name:查询的表名。特性说明
DISTINCT 可以基于单列或多列进行去重,只有多列的值完全相同时,亿华云才会被判定为重复行。在DISTINCT中,NULL 被视为一个独立的值,因此即使列中有多个 NULL 值,结果中只会保留一个 NULL。GROUP BY
GROUP BY 是一个用于分组的子句,通常与聚合函数配合使用以对分组后的数据进行汇总处理。它按指定列的值将行划分为不同的组。
基本语法
复制SELECT column1, aggregate_function(column_name) FROM table_name WHERE condition GROUP BY column1, column2, ...;1.2.3.4.参数说明:
column1, column2:分组的字段。aggregate_function(column_name) :用于对分组内的行进行计算的聚合函数,例如 COUNT, SUM, AVG 等。table_name:查询的表名字。condition:可选,用于过滤行,在分组之前应用。GROUP BY column1, column2... :定义用于分组的字段,具有相同值的行被分配到同一个组。示例表结构与数据:
为了便于说明,我们定义两个表 customers 和 orders,并插入一些示例数据。
创建表:
复制CREATE TABLE customers ( customer_id INT PRIMARY KEY, nameVARCHAR(255) NOTNULL, city VARCHAR(255) NOTNULL ); INSERTINTO customers (customer_id, name, city) VALUES (1, John Doe, New York), (2, Jane Smith, London), (3, Mike Brown, Paris), (2, Jane Smith, London); -- 存在重复项 CREATETABLE orders ( order_id INT PRIMARY KEY, customer_id INTNOTNULL, product VARCHAR(255) NOTNULL, price DECIMAL(10,2) NOTNULL, FOREIGNKEY (customer_id) REFERENCES customers(customer_id) ); INSERTINTO orders (order_id, customer_id, product, price) VALUES (1, 1, Phone, 100.00), (2, 2, Laptop, 500.00), (3, 1, Tablet, 200.00), (4, 2, Watch, 150.00);1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.SELECT DISTINCT与GROUP BY使用对比
示例 1:检索唯一的亿华云计算客户城市
场景:我们希望查询 customers 表中的唯一城市,不关心重复的城市名称。
使用 DISTINCT:
复制SELECT DISTINCT city FROM customers;1.2.输出:
复制city ----- New York London Paris1.2.3.4.5.SQL 查询去除了数据集中重复的城市,只返回唯一值,简单直观。
示例 2:按客户城市统计订单数量
场景:我们希望统计每个城市对应的订单数量,涉及分组统计。
使用 GROUP BY:
复制SELECT city, COUNT(*) AS order_count FROM customers c INNER JOIN orders o ON c.customer_id = o.customer_id GROUP BY city;1.2.3.4.输出:
复制city order_count ------------------------ London 2 New York 21.2.3.4.SQL 查询通过 GROUP BY 以城市分组,并结合 COUNT 聚合函数统计每组的订单数量,提供了更丰富的汇总信息。
SELECT DISTINCT 与 GROUP BY 的性能分析
虽然 DISTINCT 和 GROUP BY 都会涉及底层的分组操作,但在某些情况下,它们可以互换使用,而在性能、功能上的表现会有所偏差。
两者实现的相似性
对于以下两条查询:
复制SELECT DISTINCT int1_index FROM test_table; SELECT int1_index FROM test_table GROUP BY int1_index;1.2.在某些情况下(如 int1_index 上有索引),两者使用相同的执行计划。例如,通过以下 EXPLAIN 分析,查询会通过索引扫描优化:
复制mysql> explain select distinct int1_index from test_distinct_groupby; mysql> explain select int1_index from test_distinct_groupby group by int1_index;1.2.两者结果中 Extra 字段显示 Using index for group-by,说明索引用于优化查询,效率相当。免费源码下载
GROUP BY的隐式排序问题
在 MySQL 8.0 之前,GROUP BY 默认对结果进行隐式排序。这可能导致额外的排序操作(filesort),增加了查询开销。在无显式排序要求时,DISTINCT 的性能会优于 GROUP BY。
例如:
复制SELECT int6_random FROM test_table GROUP BY int6_random;1.通过 EXPLAIN 查询,可以看到隐式排序增加了开销:
复制Extra: Using filesort1.从 MySQL 8.0 开始,GROUP BY 不再强制进行隐式排序,性能接近 DISTINCT,尤其是在无索引的大数据场景下,二者效率更加一致。
SELECT DISTINCT 与 GROUP BY 的应用场景及差异
功能和目的对比:
功能
SELECT DISTINCT
GROUP BY
目的
去重
分组并聚合数据
是否支持聚合函数
否
是
排序行为
否(可选)
是(默认排序,8.0后优化)
性能
无索引场景更高效
无索引场景稍慢(排序)
语法复杂度
简单
较复杂
适用场景
根据具体需求选择 DISTINCT 或 GROUP BY:
使用SELECT DISTINCT:当仅需要去除重复项,返回唯一值时。适用于简单查询场景。使用GROUP BY:当需要按特定条件分组并对分组内的数据进行汇总或聚合(如 COUNT, SUM, AVG)时。适合复杂的业务场景,支持更多灵活的操作,如结合 HAVING 子句筛选分组后的结果。结论
SELECT DISTINCT 和 GROUP BY 是两种功能强大的工具,用于不同类型的 SQL 查询需求:
DISTINCT 适合简单去重,避免数据重复。GROUP BY 更注重分组数据并对分组进行汇总分析。在 MySQL 8.0 后,性能差距进一步缩小,但从语义清晰度与灵活性来看,GROUP BY 在处理复杂业务场景时更胜一筹。选择使用哪种方式应根据具体应用场景而定。
本文地址:http://www.bzuk.cn/html/077d6899854.html
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。