亚洲 卡通 欧美 制服 中文,午夜在线看的免费网站,黑人太大了太深了好痛 视频,国产乱妇乱子视频在播放

廣州總部電話:020-85564311
20年
互聯(lián)網(wǎng)應(yīng)用服務(wù)商
廣州總部電話:020-85564311
20年
互聯(lián)網(wǎng)應(yīng)用服務(wù)商
請輸入搜索關(guān)鍵詞
知識庫 知識庫

優(yōu)網(wǎng)知識庫

探索行業(yè)前沿,共享知識寶庫

MySQL 中的 distinct 和 group by 哪個效率更高?太刁鉆了吧!

發(fā)布日期:2025-08-21 17:51:26 瀏覽次數(shù): 807 來源:ITPUB
推薦語
MySQL面試必問的刁鉆問題:DISTINCT和GROUP BY到底誰更快?本文用實戰(zhàn)案例幫你徹底搞懂兩者的性能差異。

核心內(nèi)容:
1. 索引場景下兩者的效率對比
2. 無索引時DISTINCT的性能優(yōu)勢分析
3. GROUP BY隱藏的排序陷阱與解決方案
小優(yōu) 網(wǎng)站建設(shè)顧問
專業(yè)來源于二十年的積累,用心讓我們做到更好!

这个问题其实比很多人以为的要复杂得多,特别是面试时面试官带着“刁钻”目的来问的时候。如果你直接回一句“效率差不多”可能还真就挂了。咱们今天就来掰扯清楚:MySQL 里的 DISTINCT 和 GROUP BY,到底谁更高效,什么场景下各自更合适,以及你该怎么选。

先抛个结论出来——

在有索引并语义等价的情况下,两者几乎效率一样;但在无索引时,DISTINCT 很可能更快,GROUP BY 会拖后腿,主要是那个“filesort”惹的祸。不过光说这些还不够,你得知道为什么。

我自己在项目里就遇到过类似的情况,那时候是为了清洗数据表里的重复记录,用 GROUP BY 总感觉慢得要死,一换成 DISTINCT,结果就飞了,跑得比我早上打卡还快。

DISTINCT:不动声色地去重

我们先看 DISTINCT。这玩意儿其实逻辑挺简单:你查出来的所有列,只要整行完全一样,就认为是重复的,只保留一条。常规用法是这样:

SELECT DISTINCT age FROM student;

注意,它对你 SELECT 出来的所有字段生效,不是某个字段,而是组合后的整个“行”维度。

比如你写了:

SELECT DISTINCT sex, age FROM student;

它会认为 (male, 10) 和 (female, 10) 是不一样的,只有相同的性别 + 年龄才算重复。

性能层面来说,DISTINCT 做的是“去重”,但如果你给它一个合适的索引,比如 sex, age 的联合索引,它其实不用全表扫描,而是可以直接走索引。MySQL 执行计划里你会看到一个“Using index for group-by”的提示,虽然字面写的是 group-by,但确实也能用于 DISTINCT,这有点迷惑初学者。

GROUP BY:看似一样,实则有坑

再看 GROUP BY。你可能觉得和 DISTINCT 类似,确实在某些简单场景下是一样的,但它本质上是“分组”,然后你可以对每组做聚合。

比如:

SELECT age FROM student GROUP BY age;

这时候看起来和 DISTINCT age 差不多,都是返回不同的年龄值。

但你换成这样:

SELECT sex, age FROM student GROUP BY sex;

MySQL 会返回每个性别的第一条记录的 age,不同的引擎实现可能会选不同的 age,你不能指望它总是按你想的来。所以这个用法在逻辑上和 DISTINCT 就不等价了,结果可能不同。

而更要命的是——在 MySQL 8.0 以前,GROUP BY 是默认会排序的。也就是说哪怕你没写 ORDER BY,它也偷偷给你搞个排序。如果你选的字段没索引覆盖,MySQL 可能就得生成临时表 + filesort,这个组合就是性能黑洞:

Using temporary; Using filesort

看见这两个词,基本可以判断执行效率不会太好,特别是数据量上来了以后,能慢到你怀疑人生。

MySQL 8.0 的“优化”背锅

MySQL 8.0 改了这个默认行为,不再默认隐式排序。这本来是件好事,但也带来一个副作用:一些之前依赖这个排序特性的代码,升级后结果顺序可能变了。所以如果你用了 GROUP BY 想靠它排序,最好老老实实加上 ORDER BY

顺便说句,老版本 MySQL 想避免隐式排序,可以在 GROUP BY 后加 ORDER BY NULL,这是老派 DBA 常用的骚操作。到了 MySQL 8.0,这步就不需要了。

有索引 vs 无索引:才是关键分水岭

你可能发现了,我们上面讲的这些,性能好坏其实并不是 DISTINCT 和 GROUP BY 本身的锅,而是跟有没有用到索引强相关。

如果你用的是 DISTINCT age,而 age 刚好有个索引,那这个 SQL 可能直接走索引,连表都不用扫,效率当然高。

但如果你用了 GROUP BY age,age 没索引,MySQL 就得扫全表、创建临时表、排序,然后再分组,整个流程就重了很多。

也就是说,在“无索引”的前提下:

  • DISTINCT 去重操作,偏“纯”,只需要判断相同行是否重复
  • GROUP BY 是先分组再聚合,如果没有聚合函数,还会默认排序,开销更大

在有索引时,两者都会用上 index,最终执行计划基本相同,所以几乎没有差异。

我个人怎么选?

老实说,我更倾向用 GROUP BY。不是因为它快,而是它更灵活。你别看它一开始像是去重,其实真正的杀手锏是——你可以挂聚合函数上去。

比如:

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

一下就能知道每个年龄段有多少人,这是 DISTINCT 做不到的。

而且 GROUP BY + HAVING 可以让你对分组之后的结果再过滤,比如:

SELECT age, COUNT(*) as c FROM student GROUP BY age HAVING c > 1;

这比你用 DISTINCT 然后自己去计数、再筛选,简单太多了。

当然,如果你只是为了去重,又没啥其他操作,那 DISTINCT 就挺合适,代码也更直观些,尤其是你不打算扩展逻辑的场景。

写代码别光看“表面效率”

面试官要你比较效率,其实不是让你死记硬背谁更快,而是想看你是否知道“为什么更快”。也就是说,你得看得出:

  • 哪种写法在什么版本的 MySQL 上可能走 filesort
  • 你写的字段有没有索引
  • 查询是不是还能加聚合、筛选

我自己在处理大数据量的时候,踩过无数次 “GROUP BY filesort” 的坑,后来一看到 Using temporary; Using filesort 就条件反射去加索引或者改写逻辑了。

另外顺便提一句,DISTINCT 也不是没坑,它的“全字段作用”有时候会意外拉高去重复杂度。比如:

SELECT DISTINCT name, create_time FROM user;

如果 create_time 是毫秒级时间戳,几乎每条记录都不同,根本去不掉重复,结果集和原始数据几乎一样,效率反而更低。用 GROUP BY name + 聚合反倒更合适。

所以啊,这个问题的答案不是 “谁更快”,而是“你知道他们本质上是啥、执行计划差在哪、什么时候该用谁”。

别一上来就丢个“DISTINCT 更快”,面试官可能马上反问你“那聚合怎么算?”

你要做的是,先判断语义是不是完全一样,然后看数据量、索引、版本,再决定用哪个。顺便加上一句“我个人更喜欢用 GROUP BY,因为它更灵活”,就妥了。

優(yōu)網(wǎng)科技,優(yōu)秀企業(yè)首選的互聯(lián)網(wǎng)供應(yīng)服務(wù)商

優(yōu)網(wǎng)科技秉承"專業(yè)團隊、品質(zhì)服務(wù)" 的經(jīng)營理念,誠信務(wù)實的服務(wù)了近萬家客戶,成為眾多世界500強、集團和上市公司的長期合作伙伴!

優(yōu)網(wǎng)科技成立于2001年,擅長網(wǎng)站建設(shè)、網(wǎng)站與各類業(yè)務(wù)系統(tǒng)深度整合,致力于提供完善的企業(yè)互聯(lián)網(wǎng)解決方案。優(yōu)網(wǎng)科技提供PC端網(wǎng)站建設(shè)(品牌展示型、官方門戶型、營銷商務(wù)型、電子商務(wù)型、信息門戶型、微信小程序定制開發(fā)、移動端應(yīng)用(手機站、APP開發(fā))、微信定制開發(fā)(微信官網(wǎng)、微信商城、企業(yè)微信)等一系列互聯(lián)網(wǎng)應(yīng)用服務(wù)。


我要投稿

姓名

文章鏈接

提交即表示你已閱讀并同意《個人信息保護聲明》

專屬顧問 專屬顧問
掃碼咨詢您的優(yōu)網(wǎng)專屬顧問!
專屬顧問
馬上咨詢
聯(lián)系專屬顧問
聯(lián)系專屬顧問
聯(lián)系專屬顧問
掃一掃馬上咨詢
掃一掃馬上咨詢

掃一掃馬上咨詢

和我們在線交談!