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

点击关注公众号,Java干货及时送达066d81bddaa90e35652e194b85fbae43.png


先说大致的结论(完整结论在文末):

  • 在语义相同,有索引的情况下:group by和distinct都能使用索引,效率相同。

  • 在语义相同,无索引的情况下:distinct效率高于group by。原因是distinct 和 group by都会进行分组操作,但group by可能会进行排序,触发filesort,导致sql执行效率低下。

基于这个结论,你可能会问:

  • 为什么在语义相同,有索引的情况下,group by和distinct效率相同?

  • 在什么情况下,group by会进行排序操作?

带着这两个问题找答案。接下来,我们先来看一下distinct和group by的基础使用。

distinct的使用

distinct用法
SELECT DISTINCT columns FROM table_name WHERE where_conditions;

例如:

mysql> select distinct age from student;
+------+
| age  |
+------+
|   10 |
|   12 |
|   11 |
| NULL |
+------+
4 rows in set (0.01 sec)

DISTINCT 关键词用于返回唯一不同的值。放在查询语句中的第一个字段前使用,且作用于主句所有列。

如果列具有NULL值,并且对该列使用DISTINCT子句,MySQL将保留一个NULL值,并删除其它的NULL值,因为DISTINCT子句将所有NULL值视为相同的值。

distinct多列去重

distinct多列的去重,则是根据指定的去重的列信息来进行,即只有所有指定的列信息都相同,才会被认为是重复的信息。

SELECT DISTINCT column1,column2 FROM table_name WHERE where_conditions;
mysql> select distinct sex,age from student;
+--------+------+
| sex    | age  |
+--------+------+
| male   |   10 |
| female |   12 |
| male   |   11 |
| male   | NULL |
| female |   11 |
+--------+------+
5 rows in set (0.02 sec)

group by的使用

对于基础去重来说,group by的使用和distinct类似:

单列去重

语法:

SELECT columns FROM table_name WHERE where_conditions GROUP BY columns;

执行:

mysql> select age from student group by age;
+------+
| age  |
+------+
|   10 |
|   12 |
|   11 |
| NULL |
+------+
4 rows in set (0.02 sec)
多列去重

语法:

SELECT columns FROM table_name WHERE where_conditions GROUP BY columns;

执行:

mysql> select sex,age from student group by sex,age;
+--------+------+
| sex    | age  |
+--------+------+
| male   |   10 |
| female |   12 |
| male   |   11 |
| male   | NULL |
| female |   11 |
+--------+------+
5 rows in set (0.03 sec)
区别示例

两者的语法区别在于,group by可以进行单列去重,group by的原理是先对结果进行分组排序,然后返回每组中的第一条数据。且是根据group by的后接字段进行去重的。

例如:

mysql> select sex,age from student group by sex;
+--------+-----+
| sex    | age |
+--------+-----+
| male   |  10 |
| female |  12 |
+--------+-----+
2 rows in set (0.03 sec)

distinct和group by原理

在大多数例子中,DISTINCT可以被看作是特殊的GROUP BY,它们的实现都基于分组操作,且都可以通过松散索引扫描、紧凑索引扫描(关于索引扫描的内容会在其他文章中详细介绍,就不在此细致介绍了)来实现。

DISTINCTGROUP BY都是可以使用索引进行扫描搜索的。例如以下两条sql(只单单看表格最后extra的内容),我们对这两条sql进行分析,可以看到,在extra中,这两条sql都使用了紧凑索引扫描Using index for group-by

所以,在一般情况下,对于相同语义的DISTINCTGROUP BY语句,我们可以对其使用相同的索引优化手段来进行优化。

mysql> explain select int1_index from test_distinct_groupby group by int1_index;
+----+-------------+-----------------------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
| id | select_type | table                 | partitions | type  | possible_keys | key     | key_len | ref  | rows | filtered | Extra                    |
+----+-------------+-----------------------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
|  1 | SIMPLE      | test_distinct_groupby | NULL       | range | index_1       | index_1 | 5       | NULL |  955 |   100.00 | Using index for group-by |
+----+-------------+-----------------------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
1 row in set (0.05 sec)mysql> explain select distinct int1_index from test_distinct_groupby;
+----+-------------+-----------------------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
| id | select_type | table                 | partitions | type  | possible_keys | key     | key_len | ref  | rows | filtered | Extra                    |
+----+-------------+-----------------------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
|  1 | SIMPLE      | test_distinct_groupby | NULL       | range | index_1       | index_1 | 5       | NULL |  955 |   100.00 | Using index for group-by |
+----+-------------+-----------------------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
1 row in set (0.05 sec)

但对于GROUP BY来说,在MYSQL8.0之前,GROUP Y默认会依据字段进行隐式排序。

可以看到,下面这条sql语句在使用了临时表的同时,还进行了filesort。

mysql> explain select int6_bigger_random from test_distinct_groupby GROUP BY int6_bigger_random;
+----+-------------+-----------------------+------------+------+---------------+------+---------+------+-------+----------+---------------------------------+
| id | select_type | table                 | partitions | type | possible_keys | key  | key_len | ref  | rows  | filtered | Extra                           |
+----+-------------+-----------------------+------------+------+---------------+------+---------+------+-------+----------+---------------------------------+
|  1 | SIMPLE      | test_distinct_groupby | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 97402 |   100.00 | Using temporary; Using filesort |
+----+-------------+-----------------------+------------+------+---------------+------+---------+------+-------+----------+---------------------------------+
1 row in set (0.04 sec)
隐式排序

对于隐式排序,我们可以参考Mysql官方的解释:

https://dev.mysql.com/doc/refman/5.7/en/order-by-optimization.html

GROUP BY implicitly sorts by default (that is, in the absence of ASC or DESC designators for GROUP BY columns). However, relying on implicit GROUP BY sorting (that is, sorting in the absence of ASC or DESC designators) or explicit sorting for GROUP BY (that is, by using explicit ASC or DESC designators for GROUP BY columns) is deprecated. To produce a given sort order, provide an ORDER BY clause.

大致解释一下:

GROUP BY 默认隐式排序(指在 GROUP BY 列没有 ASC 或 DESC 指示符的情况下也会进行排序)。然而,GROUP BY进行显式或隐式排序已经过时(deprecated)了,要生成给定的排序顺序,请提供 ORDER BY 子句。

所以,在Mysql8.0之前,Group by会默认根据作用字段(Group by的后接字段)对结果进行排序。在能利用索引的情况下,Group by不需要额外进行排序操作;但当无法利用索引排序时,Mysql优化器就不得不选择通过使用临时表然后再排序的方式来实现GROUP BY了。

且当结果集的大小超出系统设置临时表大小时,Mysql会将临时表数据copy到磁盘上面再进行操作,语句的执行效率会变得极低。这也是Mysql选择将此操作(隐式排序)弃用的原因。

基于上述原因,Mysql在8.0时,对此进行了优化更新:

https://dev.mysql.com/doc/refman/8.0/en/order-by-optimization.html

Previously (MySQL 5.7 and lower), GROUP BY sorted implicitly under certain conditions. In MySQL 8.0, that no longer occurs, so specifying ORDER BY NULL at the end to suppress implicit sorting (as was done previously) is no longer necessary. However, query results may differ from previous MySQL versions. To produce a given sort order, provide an ORDER BY clause.

大致解释一下:

从前(Mysql5.7版本之前),Group by会根据确定的条件进行隐式排序。在mysql 8.0中,已经移除了这个功能,所以不再需要通过添加order by null 来禁止隐式排序了,但是,查询结果可能与以前的 MySQL 版本不同。要生成给定顺序的结果,请按通过ORDER BY指定需要进行排序的字段。

因此,我们的结论也出来了:

  • 在语义相同,有索引的情况下:

group by和distinct都能使用索引,效率相同。因为group by和distinct近乎等价,distinct可以被看做是特殊的group by

  • 在语义相同,无索引的情况下:

distinct效率高于group by。原因是distinct 和 group by都会进行分组操作,但group by在Mysql8.0之前会进行隐式排序,导致触发filesort,sql执行效率低下。

但从Mysql8.0开始,Mysql就删除了隐式排序,所以,此时在语义相同,无索引的情况下,group by和distinct的执行效率也是近乎等价的。

推荐group by的原因

  1. group by语义更为清晰

  2. group by可对数据进行更为复杂的一些处理

相比于distinct来说,group by的语义明确。且由于distinct关键字会对所有字段生效,在进行复合业务处理时,group by的使用灵活性更高,group by能根据分组情况,对数据进行更为复杂的处理,例如通过having对数据进行过滤,或通过聚合函数对数据进行运算。

版权声明:本文为CSDN博主「猾枭」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/weixin_42615847/article/details/118342524

热门内容:
因ChatGPT爆红的大数据培养计划|拿不到年薪25W全额退款用上这几个开源管理系统做项目,领导看了直呼专业!
  • ChatGPT 连夜迭代:你老婆不好使了

  • 动态可监控线程池,你还没用起来吗?

 

c6abc8be8ef4eef3525a0325b441126c.jpeg

 
最近面试BAT,整理一份面试资料《Java面试BAT通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。
获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。

明天见(。・ω・。)

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

美团:这个 SQL 语句加了哪些锁?

点击关注公众号,Java干货及时送达👇 美团问数据库应该是非常多的,尤其喜欢考手写 SQL 然后问你这个 SQL 语句上面加了哪些锁,你会发现其他厂面试基本很少会这样考,所以很多小伙伴遇到这种问题的时候都是一脸懵逼&#…

顶级Javaer都在使用的类库,真香!

点击关注公众号,Java干货及时送达👇 来源:网络 1.日志库2.JSON解析库3.单元测试库4.通用库5.HTTP 库6.XML 解析库7.Excel 阅读库8.字节码库9.数据库连接池库10.消息库11.PDF 库12.日期和时间库13.集合库14.电子邮件 API15.HTML 解析库16.密码…

让ChatGPT长“手”!Meta爆火新论文,让语言模型学会自主使用工具

鱼羊 Pine 发自 凹非寺量子位 | 公众号 QbitAI ChatGPT爆火,Meta也坐不住了。 微软和谷歌正在搜索引擎那边刺刀拼刺刀呢,谁想Meta冷不防抛出一篇新论文,顿时吸引全场目光: 瞄准ChatGPT的“软肋”,让大语言模型自行学会…

OpenAI 何以掀翻 Google 布局多年的AI大棋?

来源: 飞哥说AI 作者|高佳 创意|李志飞 任何大卫击败歌利亚的故事, 都值得我们重新思考。 2023年从一场巨头之间的巨额合作开始,一场汹涌已久的AI暗战摆上了台面。 随着微软和 OpenAI 融资的推进,双方…

AIGC之GPT-4:GPT-4的简介(核心原理/意义/亮点/技术点/缺点/使用建议)、使用方法、案例应用(计算能力/代码能力/看图能力等)之详细攻略

AIGC之GPT-4:GPT-4的简介(核心原理/意义/亮点/技术点/缺点/使用建议)、使用方法、案例应用(计算能力/代码能力/看图能力等)之详细攻略 解读:在2022年11月横空出世的ChatGPT,打遍天下无敌手的时候,就知道会有这么一天,知…

宇宙最强-GPT-4 横空出世:最先进、更安全、更有用

文章目录 前言一、准确性提升1.创造力2.视觉输入3.更长的上下文 二、相比于ChatGPT有哪些提升1.GPT-4 的高级推理能力超越了 ChatGPT2.GPT-4 在多种测试考试中均优于 ChatGPT。 三、研究团队在GPT-4模型都做了哪些改善1.遵循 GPT、GPT-2 和 GPT-3 的研究路径2.我们花了 6 个月的…

ChatGPT五分钟写完插件,功能完善,还可加需求改BUG

开发者(KaiFaX) 面向全栈工程师的开发者 专注于前端、Java/Python/Go/PHP的技术社区 詹士 发自 凹非寺量子位 | 公众号 QbitAI ChatGPT写代码,水平究竟如何? 不到5分钟,做出一个WordPress(一款内容管理系统…

ChatGPT无限可能性:自然语言生成的奥秘

💗wei_shuo的个人主页 💫wei_shuo的学习社区 🌐Hello World ! ChatGPT无限可能性:自然语言生成的奥秘 数字化时代:跨越语言和文化障碍 冰岛是北大西洋中部的一个岛国,拥有充满活力的科技产业和…

太香了!用chatGPT写正则

chatGPT热度一直持续不下,我们普通人能做什么? 当然是先用起来,和自己工作结合起来,提高效率。 日常工作中正则使用少不了,可以让gpt来写正则,再也不用去小度查了。 今天推荐下朋友开发的gpt 正则工具&…

一个评测模型+10个问题,摸清盘古、通义千问、文心一言、ChatGPT的“家底”!...

‍数据智能产业创新服务媒体 ——聚焦数智 改变商业 毫无疑问,全球已经在进行大模型的军备竞赛了,“有头有脸”的科技巨头都不会缺席。昨天阿里巴巴内测了通义千问,今天华为公布了盘古大模型的最新进展。不久前百度公布了文心一言、360也公布…

【前沿技术】问答pk【ChatGPT Vs Notion AI Vs BAT AI 】

目录 写在前面 问题: 1 ChatGPT 1.1 截图 ​1.2 文字版 2 Notion AI 2.1 截图 2.2 文字版 3 BAT AI 3.1 截图 3.2 文字版 总结 序言 所有幸运和巧合的事,要么是上天注定,要么是一个人偷偷的在努力。 突发奇想,问三个…

前京东AI掌门人周伯文入局ChatGPT,亲手创立的衔远科技获天使轮融资数亿元!

日前,全球领先的专注于企业创新数智化的技术服务公司衔远科技宣布已经完成数亿元天使轮融资,本轮融资由启明创投领投,经纬创投跟投。 衔远科技成立于2021年底,致力于让每一件商品都应需而生,让每一位消费者都得偿所愿。…

前京东AI掌门人入局ChatGPT!「不设上限」招揽中国OpenAI合伙人

鱼羊 发自 凹非寺量子位 | 公众号 QbitAI4 又一技术大牛官宣入局ChatGPT。 这一回出手的,是被视作“京东AI开创者”的前京东高级副总裁,周伯文。 就在2月26日晚间,周伯文在朋友圈广发“英雄帖”,称“现不设上限诚招合伙人”&#…

AI落地:程序员如何用AI?

对于程序员来说,真正能提高效率、可落地的AI应用场景都有哪些? 目前已经能切实落地,融入我日常工作生活的有以下几个场景: 开发工作:自然语言生成代码,自动补全代码 日常工作学习:写作、翻译、…

我的周刊(第079期)

我的信息周刊,记录这周我看到的有价值的信息,主要针对计算机领域,内容主题极大程度被我个人喜好主导。这个项目核心目的在于记录让自己有印象的信息做一个留存以及共享。 🎯 项目 ChatGPT 项目推荐 基于 ChatGPT 相关接口衍生的项…

中小学教师ChatGPT的23种用法!

中小学教师ChatGPT的23种用法! 近日,ChatGPT引发舆论风暴,火遍全球。作为一款生成式人工智能软件,ChatGPT可以就任何议题生成文本,完成包括回答问题,撰写文章、论文、诗歌在内的多种工作。各界盛赞其“有着…

【软件架构思想系列】分层架构

目录 架构思维概述 “分解+集成” 可以理解为架构最核心的思考方式和方法。

K8S 生态周报| 别慌,DockerHub 不会清退开源组织和开源项目

“ 「K8S 生态周报」内容主要包含我所接触到的 K8S 生态相关的每周值得推荐的一些信息。欢迎订阅知乎专栏「k8s生态」[1]。 ” 大家好,我是张晋涛。 DockerHub 将停止个人免费版 Team 的功能 想必很多人都用过 DockerHub,Docker 刚面世的时候&#xff0c…

ChatGPT,太爆了!

大家好啊,我是了不起,一个热爱开源的程序员~ 自从去年 ChatGPT 刚刚推出的时候,我们团队就上手体验过,当时就让我感觉到非常的震惊:使用好她,绝对能将工作效率提升好几倍! 这是当时做的几个小测…

AIGC技术周报|清华、北邮新研究:让文生图AI更懂你

AIGC通过借鉴现有的、人类创造的内容来快速完成内容创作。ChatGPT、Bard等AI聊天机器人以及DallE 2、Stable Diffusion等文生图模型都属于AIGC的典型案例。「AIGC技术周报」将为你带来最新的paper、博客等前瞻性研究。 OpenAGI:当大模型遇见领域专家 “愿原力与大型…