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

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

二、优化之前的sql长这样是不是挺恐怖的;(此处为了脱敏,我把相关的sql关键词都给打码掉了)

这个sql的执行步骤如下:

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

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

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

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

三、DISTINCT关键字的用法实践是验证真理的唯一标准

例如有下表:可以看到name和product_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>是不是很简单,虽然看着简单,但是如果多表子查询的时候,就会出现问题,例如你想要查询表a,b,c三个表的数据,这三个表必然都是有关系的。

a和b是1-n的关系。但是你只有b表中id,你需要先查询出来b表的数据,然后利用b表的数据去查询a表的数据,然后再去查询c表的数据。

想必肯定是很绕的。

整个过程中你肯定是需要去重的

当整个sql写完,基本上跟我写的优化前的sql也就差不多了。(多表嵌套,多sql嵌套sql,啦啦啦一大堆)。

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

四、谈:如何优化distinct的sql

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

推荐大家阅读。

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:如果在查询中不适用来自所有表的列,MySQL一旦找到第一个匹配项就会停止扫描任何未使用的表。

在下面的例子中,假设t1在t2之前使用(你可以使用explanin来检查),MySQL在找到t2的第一行时停止从t2读取(对于t1中的任何特定行)。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长啥样?怎么样,改造后的sql,是不是还挺清爽的。

1、我们扔掉了多个嵌套sql;

2、也不用去生成一个sss的临时表了

七、总结

对于本人而言学到了:1、distinct与group by几乎等价;

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

3、如果distinct的不能让sql最优化,那么可以尝试着使用group by的方式去改造一下。

mysql distinct 优化_SQL优化终于干掉了“distinct”相关推荐

  1. SQL优化终于干掉了“distinct”

    SQL优化之多表联合查询干掉"distinct"去重关键字 一.优化目的 二.优化之前的sql长这样 三.DISTINCT关键字的用法 四.谈:如何优化distinct的sql 五 ...

  2. 不可置信!SQL 优化终于干掉了“distinct”

    sql 优化之多表联合查询干掉 "distinct" 去重关键字 在我提交了代码的时候,架构师给我指出我这个sql这样写会有问题.因为在分库分表的时候,是不支持子查询的. 所以需要 ...

  3. mysql 分区表优化_Sql优化之Mysql表分区

    一  分区表适用于以下场景 1:表非常大以至于无法全部放在内存中,或者只在标的最后部分有热点数据,其他均是历史数据 2:分区表的数据更容易维护.例如想批量删除大量数据可以使用清除整个分区的方式.另外还 ...

  4. mysql 笛卡尔积影响_SQL优化 MySQL版 -分析explain SQL执行计划与笛卡尔积

    SQL优化 MySQL版 -分析explain SQL执行计划 作者 Stanley 罗昊 [转载请注明出处和署名,谢谢!] 首先我们先创建一个数据库,数据库中分别写三张表来存储数据; course: ...

  5. mysql 单表查询 优化_SQL优化 MySQL版 - 单表优化及细节详讲

    单表优化及细节详讲 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 注:本文章需要MySQL数据库优化基础或观看前几篇文章,传送门: B树索引详讲(初识SQL优化,认识索引):htt ...

  6. mysql 大于号 优化_SQL优化 MySQL版 - 避免索引失效原则(二)

    避免索引失效原则(二) 注:继上一篇文章继续讲解: 避免索引失效原则(一)https://www.cnblogs.com/StanleyBlogs/p/10482048.html#4195062 作者 ...

  7. 百度 mysql的sql优化_SQL优化问题

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 SELECT cust.code, org.name4 district, org.name3 center, org.name2 org, org.na ...

  8. sql的不等于条件优化_SQL优化案例(2):OR条件优化

    随后上一篇文章< SQL优化案例(1):隐式转换>的介绍,此处内容围绕OR的优化展开. 在MySQL中,同样的查询条件,如果变换OR在SQL语句中的位置,那么查询的结果也会有差异,在多个复 ...

  9. 在Ubuntu上源码安装MySQL+安装问题解决+安全优化

    当然,MySQL的安装方法多种多样,在Ubuntu上,你可以采用apt-get的方式安装,这样的好处是:快速方便.基本上,它会帮你解决所有的函数库依赖问题,正常情况下,只要apt-get执行完成,那么 ...

最新文章

  1. mysql status改变_mysql 配置详解mysql SHOW STATUS 详解
  2. Spring Boot 发起 HTTP 请求
  3. 关于HTTP协议及SOCKET通信
  4. 不同编程语言能耗不同?看这27种语言对比!
  5. 一篇关于《1984》读后感
  6. java基础—Date类的常见方法演示
  7. dubbo通信协议之对比
  8. oracle sql不用distinct去除重复,oracle sql 去重复记录不用distinct如何实现
  9. 巧设IP路由 实现不同网段互通
  10. python comprehension_Python从题目中学习:List comprehension
  11. 经典问题:流水线调度(51nod)
  12. 非广告,运维派送红包,参与就有!
  13. 怪物之心无法触发_《勇者斗恶龙 怪兽篇:旅团之心》怪物生方法及生规则研究 - 电玩巴士...
  14. 学习笔记12--智能驾驶安全设计案例
  15. 直播app开发公司手把手搭建一套简单的直播系统
  16. PLC转行嵌入式软件开发的辛路历程
  17. 网络协议MPL(3):RFC2606--The Trickle Algorithm文档翻译
  18. 5.3 用户注册与登录
  19. 笔记本整机性能测试软件,整机性能测试_笔记本评测-中关村在线
  20. 2022年低压电工考试题及答案

热门文章

  1. UNIX环境高级编程源码
  2. xgb.cv进行交叉验证
  3. #Eclipse IDE for Java EE Developers 的下载及初步使用
  4. Excel VBA(04)数组和字典
  5. Qt下MQTT模块的导入(源码直接导入)适用Windows和Linux系统
  6. 【Linux】【Kernel】BUG: scheduling while atomic问题分析
  7. MATLAB中画折线图:plot函数的简单用法
  8. Java——随机生成4位验证码,由用户输入并验证是否输入正确,如果输入错误就生成新的验证码让用户重新输入,最多输入5次
  9. RHCE 第二周作业
  10. 硬编码失败问题Codec reported err 0x80000000, actionCode 0, while in state 5