社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  DATABASE

京东一面:MySQL 中的 distinct 和 group by 哪个效率更高?太刁钻了吧!

鸭哥聊Java • 2 周前 • 37 次点击  

这题确实有点“京东味”了,面是越来越像笔试,但说实话,考这个不算过分,甚至还挺实用。

别看是个小小的“DISTINCT vs GROUP BY”,真到项目里写SQL,少说几行“Using filesort”都能省不少性能。今天我就从一个Java工程师的视角,把这个话题掰开了聊聊,不光告诉你哪个更快,还会告诉你为啥这么设计,以及,怎么避坑。

DISTINCT 和 GROUP BY,表面兄弟,实际大不同

先说句实话,DISTINCT 和 GROUP BY 在结果上看似能“干一样的事”,但实现细节差别还是挺大的。咱就拿最基础的单字段去重来说,两者都能搞定,比如:

SELECT DISTINCT age FROM student;
SELECT age FROM student GROUP BY age;

乍一看结果一样,四个年龄值,连 NULL 都是一样的。但是底层执行计划可不一定一样,这得看有没有索引。

如果 age 上有索引,那恭喜,DISTINCT 和 GROUP BY 都能走索引,执行效率都不差,EXPLAIN 一看 “Using index for group-by”,这个稳了。

但如果没有索引,那事情就开始分岔了...

无索引时,GROUP BY 容易“翻车”

这是个很多人踩过的坑。GROUP BY 的一个“坏习惯”是,早期版本(比如 MySQL 5.7)会默认给结果做个排序。这看起来挺贴心的,不用你写 ORDER BY,默认就排了序,但其实是“用爱发电”:全表扫描 + 排序 + 分组,这一套下来很容易上临时表 + filesort,慢得你头皮发麻。

举个我项目里的真实例子,当时有个报表统计写了个 group by,运行很慢,EXPLAIN 一看,“Using temporary; Using filesort”,一查 age 字段没索引,那就对了,全靠内存和CPU怼,量一大就爆。

反过来看 DISTINCT,它只需要判断是否重复,数据量不大时内存处理就能搞定,操作更“干净利落”。

所以同样无索引,DISTINCT 更快是真的。

MySQL 8.0 之后,GROUP BY 洗心革面了

不过,也不能一直黑 GROUP BY,MySQL 8.0 做了个大升级,默认不再隐式排序。以前你为了取消默认排序得写 ORDER BY NULL,现在连这都不用了,GROUP BY 终于只做分组这件事,效率一下子就上去了。

所以从 8.0 起,无索引时两者效率也差不多了,区别开始不那么明显。

别被语法迷惑,业务语义才是王道

说到底,用哪一个不是只看谁更快,还得看你到底想干啥。

DISTINCT 更适合纯去重,你要的就是那些不重复的组合值,用它写着简洁明了。

GROUP BY 就灵活多了,不光能分组,还能用 HAVING 做条件过滤,用聚合函数做统计,比如:

SELECT age, COUNT(*) FROM student GROUP BY age HAVING COUNT(*) > 2;

这个 DISTINCT 就干不了,它不是干这行的。

所以如果只是查重复项,DISTINCT 是首选;但一旦牵涉到聚合操作或者分组过滤,GROUP BY 才是你该找的搭档。

索引优化别偷懒,不然写啥都慢

写 SQL,最怕的一种心态是“它能跑就行”,这种人最容易在生产上出事。

无论你用 DISTINCT 还是 GROUP BY,只要字段没索引,数据一多都得遭罪。而且别以为走了索引就一定快,还得看是不是合适的索引,是否能覆盖查询(covering index),EXPLAIN 跑一跑,一目了然。

比如像这种就不错:

CREATE INDEX idx_age_sex ON student(age, sex);

再来个:

SELECT DISTINCT age, sex FROM student;

这时候 EXPLAIN 通常能走 “Using index”,这才是你该高兴的点,不是语法,而是执行计划。

其实我更愿意你看完之后心里能冒出几个实际问题:

  • 我的 SQL 哪些用了 GROUP BY,但没索引?
  • 项目中用 DISTINCT 的地方,是不是还能再加点聚合统计?
  • 当前数据库版本到底是 5.7 还是 8.0?差异在哪儿?
  • 执行慢的 SQL,EXPLAIN 到底都说了什么?

DISTINCT 和 GROUP BY,这种看似“数据库基础题”的东西,最容易被轻视。但讲真,一个系统的大部分慢 SQL,基本都出在这些基础上。

说到底,数据库优化就是“术”和“道”的结合。术是索引、扫描、排序、filesort这些东西,道是你有没有真正理解每个语句的意图。

要真把这些搞明白了,别说是面试,项目中的老大难SQL你都敢一条一条拿出来重写。

你最近有没有碰到执行慢但看不出问题的 SQL?或许真该回头看看,是不是这些“基础语法”在搞鬼。

最后,我为大家打造了一份deepseek的入门到精通教程,完全免费:https://www.songshuhezi.com/deepseek


同时,也可以看我写的这篇文章《DeepSeek满血复活,直接起飞!》来进行本地搭建。

对编程、职场感兴趣的同学,可以链接我,微信:yagebug  拉你进入“程序员交流群”。
🔥鸭哥私藏精品 热门推荐🔥

鸭哥作为一名老码农,整理了全网最全《Java高级架构师资料合集》
资料包含了《IDEA视频教程》 《最全Java面试题库》、最全项目实战源码及视频》及《毕业设计系统源码》总量高达 650GB 。全部免费领取!全面满足各个阶段程序员的学习需求。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/182448
 
37 次点击