跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

mysql中distinct和groupby哪个更高效_去重原理与执行路径对比

DISTINCT是专为去重设计的语义操作,GROUP BY本质用于分组聚合;仅需去重时,DISTINCT逻辑更轻、优化路径更直接,无索引时GROUP BY可能多触发Using filesort。 MySQL 中
DISTINCT
和
GROUP BY
去重,本质不是“谁更快”,而是“谁更贴合语义” 直接说结论:
DISTINCT
是专为去重设计的语义操作,
GROUP BY
是为分组聚合设计的;当仅需去重、不带聚合时,
DISTINCT
逻辑更轻、优化路径更直接。强行用
GROUP BY
实现纯去重,MySQL 有可能多走一步排序(
Using filesort
),尤其在无索引列上。
DISTINCT
的执行路径:哈希去重 or 索引扫描,不默认排序 MySQL 对
DISTINCT
的常见实现方式有两种: 小结果集:构建内存哈希表,逐行插入并去重,最后输出; 有覆盖索引时:直接走
Using index for group-by
(注意名字里有 group-by,但实际是优化器复用路径,并不真做分组); 不强制对结果排序,除非你显式加了
ORDER BY
; 例如:
SELECT DISTINCT city FROM users;
如果
city
有索引,Explain 显示
type: index
+
Extra: Using index
,基本就是索引扫描一遍完事。
GROUP BY
的执行路径:分组 → 排序(可能)→ 取首行 即使你只写
SELECT city FROM users GROUP BY city;
,MySQL 内部仍按分组逻辑处理: MySQL(Linux) MySQL 9.6.0是面向Linux平台的2026年创新版本,核心架构迎来重大革新。其将外键约束与级联操作从InnoDB引擎层上移至SQL层,确保所有数据变更均被完整记录至Binlog,彻底解决了CDC(变更数据捕获)与主从复制中的数据不一致难题。此外,该版本引入container_aware启动选项以原生适配容器环境,并对审计日志进行了组件化重构,为追求极致数据一致性与云原生体验的开发者提供了全新选择。 下载 若
city
无索引:先建临时表,再对分组键排序(触发
Using filesort
),然后每组取第一行; 若
city
有索引且是前导列:可走松散/紧凑索引扫描,跳过排序,效率接近
DISTINCT
; 一旦语句里出现非分组列(如
SELECT city, name FROM users GROUP BY city
),MySQL 5.7+ 默认报错(
sql_mode=only_full_group_by
),必须用聚合函数或明确指定取值逻辑; 所以,
GROUP BY
在纯去重场景下,多一层语义负担和潜在排序开销。 什么时候
GROUP BY
反而更优?别被“去重”二字带偏 真正影响选择的不是“哪个快”,而是你要不要后续扩展能力: 需要统计每个城市的用户数?必须用
GROUP BY city COUNT(*)
,
DISTINCT
不支持聚合; 要去重后过滤分组(比如只保留出现次数 ≥ 5 的城市)?只能用
HAVING
,
DISTINCT
没这功能; 要联合多列去重,且其中一列有高基数索引(如
(status, created_at)
),
GROUP BY
有时能更好利用覆盖索引,避免回表; 简单说:没聚合就用
DISTINCT
;要聚合、要
HAVING
、要复用已有复合索引结构,就选
GROUP BY
—— 效率差异往往藏在索引是否匹配、是否触发
filesort
这些细节里,而不是关键字本身。

相关文章