SQL优化终于干掉了“distinct”

SQL优化终于干掉了“distinct”sql 优化之多表联合查询干掉 distinct 去重关键字

一、优化目的

在我提交了代码的时候,架构师给我指出我这个sql这样写会有问题。因为在分库分表的时候,是不支持子查询的。

所以需要把多表的子查询的sql结构进行优化。

二、优化之前的sql长这样

是不是挺恐怖的;(此处为了脱敏,我把相关的sql关键词都给打码掉了)

在这里插入图片描述
这个sql的执行步骤如下:
1、查询出来d表中的某个id字段包含多个id值的所有的数据(因为此表是1-n的关系,所以需要去重,仅需要拿到不重复的id才可以继续下一个步骤);可以看到此步骤我把查询出来的多个值的结果给生成的了一个子表名为sss;




2、下一个步骤就是需要进行排序(以时间进行倒序排序,因为要在前台进行按时间进行展示);

3、第3步就是把这些结果与a表进行合并,查询出来排序后的每个id的信息;然后进行分页处理;

其他的可以不必关心,最终要的是去重关键字(DISTINCT),拿小本本记号,一会要考哦。

三、DISTINCT关键字的用法

实践是验证真理的唯一标准

例如有下表:

可以看到nameproduct_unit列有可能是重复的

mysql> SELECT t1.id,t1.name,t1.product_unit FROM dd_product_category t1; +----+----------+--------------+ | id | name | product_unit | +----+----------+--------------+ | 55 | 饮料 || | 56 | 饮料 || | 57 | 零食 || | 59 | 膨化食品 || | 60 | 方便食品 || | 61 | 自热火锅 || | 62 | 方便面 || | 63 | 矿泉水 || | 64 | 糖果 | | | 65 | 酒类 || | 66 | 烈酒 || | 67 | 啤酒 || | 68 | 预调酒 || +----+----------+--------------+ 13 rows in set (0.13 sec) mysql> mysql> 

如何我们想只拿到name或者product_unit列的值并且不想要重复的值该怎么办?

1、拿到单个值是好拿的,但是是存在重复的数据的,这些重复的数据我们只保留一个就可以了,那么该怎么做呢?

 mysql> SELECT t1.product_unit FROM dd_product_category t1; +--------------+ | product_unit | +--------------+ || || || || || || || || | | || || || || +--------------+ 13 rows in set (19.31 sec) mysql> 

2、去除重复列

mysql> mysql> SELECT DISTINCT t1.product_unit FROM dd_product_category t1; +--------------+ | product_unit | +--------------+ || || || || || | | +--------------+ 6 rows in set (0.11 sec) mysql> 

优化思路还是有很多的,当时能想到的就是把这个复杂的sql拆分成多个简单的sql执行,然后使用Java后台代码进行处理。(对于不甘于现状的我,想找到一个比这个更友好的解决方案的我,我是不会屈服这个问题的。

四、谈:如何优化distinct的sql

说到这里,先给大家放上一个链接:

  • 1、(Mysql5.7官方手册中提及到的关于优化distinct的方法)
    https://dev.mysql.com/doc/refman/5.7/en/distinct-optimization.html

  • 2、还有一个优化group by的:
    https://dev.mysql.com/doc/refman/5.7/en/group-by-optimization.html

推荐大家阅读。

Mysql5.7官方手册中提及到的关于优化distinct的方法,原文如下:

MySQL 5.7 Reference Manual / … / DISTINCT Optimization

8.2.1.16 DISTINCT Optimization

DISTINCT combined with ORDER BY needs a temporary table in many cases.

distinct 与order by 结合的许多情况下需要建一个临时表;

Because DISTINCT may use GROUP BY, learn how MySQL works with columns in ORDER BY or HAVING clauses that are not part of the selected columns. See Section 12.20.3, “MySQL Handling of GROUP BY”.

因为distinct可能使用group by,了解MySQL如何处理按order by 列或者具有不属于所选列的子句。见12.20.3节, “MySQL Handling of GROUP BY”.

In most cases, a DISTINCT clause can be considered as a special case of GROUP BY. For example, the following two queries are equivalent:

在大多数情况下,一个不同的子句可以被认为是group by 的特殊情况。例如下面这两个查询是等价的:

SELECT DISTINCT c1, c2, c3 FROM t1 WHERE c1 > const; 
SELECT c1, c2, c3 FROM t1 WHERE c1 > const GROUP BY c1, c2, c3; 

Due to this equivalence, the optimizations applicable to GROUP BY queries can be also applied to queries with a DISTINCT clause. Thus, for more details on the optimization possibilities for DISTINCT queries, see Section 8.2.1.15, “GROUP BY Optimization”.

由于这种等价性,适用于group by查询的优化,也可以应用于具有不同子句的查询。因此,关于distinct的查询优化的更多细节可以参考Section 8.2.1.15, “GROUP BY Optimization”.

When combining LIMIT row_count with DISTINCT, MySQL stops as soon as it finds row_count unique rows.

当row_count与distinct一起使用时,MySQL一旦发现row_count是唯一的行,就会停止。

If you do not use columns from all tables named in a query, MySQL stops scanning any unused tables as soon as it finds the first match. In the following case, assuming that t1 is used before t2 (which you can check with EXPLAIN), MySQL stops reading from t2 (for any particular row in t1) when it finds the first row in t2:

SELECT DISTINCT t1.a FROM t1, t2 where t1.a=t2.a; 

官方的手册中写到的,真是句句扣心呀!!!

总结有以下比较重要的几点:

  • 1、distinct与group by几乎等价;
  • 2、distinct的相关优化与group by的查询优化方法是等价的;

五、distinct真的和group by等价吗?

我们抱着试试看的态度,去做个试验。

就以下列这个效果为最终目的好了:

mysql> mysql> SELECT DISTINCT t1.product_unit FROM dd_product_category t1; +--------------+ | product_unit | +--------------+ || || || || || | | +--------------+ 6 rows in set (0.11 sec) mysql> 

使用group by去重:

mysql> select t1.product_unit from dd_product_category t1 group by t1.product_unit; +--------------+ | product_unit | +--------------+ | | || || || || || +--------------+ 6 rows in set (19.46 sec) mysql> 

可以看到,最终拿到的数据是一模一样的。

那么我们试验是成功的,distinct的效果和group by的效果是一样的。

那么我们优化distinct就变向的去优化group by了(我优化前的sql并未使用group by所以谈不上优化group by,只能说是把distinct的复杂sql改造成group by 的sql)。









由于原文比较长,这里就不在过多赘述。

现在需要做的就是把distinct改造成group by的sql语法的写法。

六、优化后的sql长啥样?

在这里插入图片描述

七、总结

对于本人而言学到了:

  • 1、distinct与group by几乎等价;
  • 2、distinct的相关优化与group by的查询优化方法是等价的;
  • 3、如果distinct的不能让sql最优化,那么可以尝试着使用group by的方式去改造一下。

为了防止链接丢失可以关注公众号,回复:"mysql"。即可拿到MySQL相关的全部精彩内容。

欢迎一起学习,一起交流,一起进步。

关注我微信公众号第一时间推送给你精彩内容哦:

回复菜单,更有好礼,惊喜在等着你。

在这里插入图片描述

快来我粉丝群:每天欢快的玩耍(微信扫描二维码即可加入,群马上满,抓紧啦!!!)
在这里插入图片描述

2020.10.14更【来自评论区大佬的精彩观点】

感谢煎蛋没有蛋这位大佬提出的精彩观点

CSDN博客名:煎蛋没有蛋:

有distinct其实一方面也代表着表连接不到位或查询条件限制不到位或者是表结构设计不合理。

博主客气了,在传统的范式模型中,的确不应该出现这样的去重问题,你想取不重复的单位 应该有单位表;产品,应该有产品表,产品表中只有单位的id,取单位的名称直接查询单位表即可。但是在olap的场景下,现在都是拿空间换时间的,所以也有可能出现冗余字段的,只是从职业习惯上,一般看到需要去重的地方,都会回去扒拉下代码,看看是不是出了笛卡尔积。

附上大佬的博客地址:https://me.csdn.net/weixin_,看得出来,是一位真大佬无疑了!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/226259.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月16日 下午11:58
下一篇 2026年3月16日 下午11:58


相关推荐

  • js动画效果_js动画函数

    js动画效果_js动画函数一、setTimeoutVS.requestAnimationFrame传统js动画实现一般使用setTimeout/setInterval等定时方式执行一个动画更新操作,但这种方式在使用中存在一些问题。动画帧间隔interval问题大部分显示器的刷新频率是16.7ms,如果setTimeout的interval小于这个值,就会出现绘制的帧无法在显示器上展现的问题,好像被吞掉了一样。另

    2022年10月15日
    5
  • 《TCP/IP详解 卷1:协议》PDF分享

    《TCP/IP详解 卷1:协议》PDF分享TCP IP 详解 一共三卷 其中卷二 卷三更多偏重于编程细节 而卷一更多偏重于基础原理 基本上都是通过实验先看现象 然后再来引出其背后的原理 所以如果没有什么基础 还是踏踏实实从头看 这对于网络工程师 软件工程师同样适用 对于嵌入式工程师 这其实也很适用 网络从提出到现在 过去了那么多年 还是一直被使用着 这足以见到网络的强大之处 而原理的东西 是根本 因此我很建议大家认真读 不过在嵌入式上 很

    2026年3月19日
    2
  • 闫学灿acwing_AAU BBU RRU

    闫学灿acwing_AAU BBU RRU给定一个包含 n 个点 m 条边的有向图,并给定每条边的容量,边的容量非负。图中可能存在重边和自环。求从点 S 到点 T 的最大流。输入格式第一行包含四个整数 n,m,S,T。接下来 m 行,每行三个整数 u,v,c,表示从点 u 到点 v 存在一条有向边,容量为 c。点的编号从 1 到 n。输出格式输出点 S 到点 T 的最大流。如果从点 S 无法到达点 T 则输出 0。数据范围2≤n≤1000,1≤m≤10000,0≤c≤10000,S≠T输入样例:7 14 1 71 2

    2022年8月9日
    9
  • kafka和flume的区别

    kafka和flume的区别1 kafka 和 flume 都是日志系统 kafka 是分布式消息中间件 自带存储 提供 push 和 pull 存取数据功能 flume 分为 agent 数据采集器 sourcechanne 2 kafka 做日志缓存应该是更为合适的 但是 flume 的数据采集部分做的很好 可以定制很多数据源 减少开发量 所以比较流行 flume kafka 模式 如果为了利用 flume 写 hdfs 的能力 也可以采用 kafka flume 的方式 采集层主要可以使用 Flume Kafka 两种技术 Flume Fl

    2026年3月18日
    3
  • egg yolk_人类蛋白数据库

    egg yolk_人类蛋白数据库欢迎关注”生信修炼手册”!直系同源蛋白的预测在系统发育,比较基因组学等多个领域都占用重要地位,COG数据库开创了同源蛋白数据库的先河,后续又不断有新的数据库涌现,而eggNOG就是目前使…

    2025年6月30日
    7
  • 食品生物技术学计算机吗,食品生物技术「建议收藏」

    食品生物技术学计算机吗,食品生物技术「建议收藏」三、教学任务食品生物技术系主要承担本科生的课程如下:生物化学、微生物学、食品营养与卫生学、食品生物技术、实验设计与数据处理、综合性实验课等课程。承担生物化工和食品科学专业研究生高等生物化学、高等微生物学、实验动物学、现代生物技术等课程。四、主要研究方向与内容  食品生物技术系主要从事与食品生物技术方向的教学、科研及甜菜分子生物学方向的科研、研究生培养工作。1.食品分子营养与安全1.1食品分子营养学…

    2022年7月11日
    18

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号