从 LeetCode 的题目再看 MySQL Explain(下)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: Hello 大家好,我是阿粉,作为 Java 工程师,数据库用的最多的肯定是 MySQL,而对于 MySQL 公号前面也发过很多文章,感兴趣的可以去翻翻。今天阿粉主要是想通过 LeetCode 上面的一个题目来再带大家看看 MySQL 的变量使用以及通过 Explain 的解析看看SQL 的执行过程。虽然平时在工作中对于 MySQL 使用的很多,但是相对于 MySQL 的变量使用相对还是较少的,所以阿粉在刚看到的时候还是有点懵的,不过我相信大家肯定不会像阿粉一样,毕竟能关注我们公众号的读者都是优秀的。

SQL 拆解

首先这条 SQL 里面有这么几个地方让阿粉迷惑,第一个是@ 符号,然后是:= 然后还有个 case when then 语法,平日里在 CRUD 的时候没遇到过这种写法,不过不知道没关系,Google 一下就好了。网上查了下,@prev 表示的是声明变量,:=操作是 MySQL 的赋值操作,case when thenwhen 后面接的是判断条件,条件成立则会返回then 后面的结果,需要注意的是 case 只会返回第一个符合条件的结果,剩下将会被忽略。

简单的了解了上面几个知识点过后,我们就可以对下面这条 SQL 进行拆解了。

select distinct Num as ConsecutiveNums
from (
  select Num, 
    case 
      when @currnet = Num then @count := @count + 1
      when (@currnet := Num) is not null then @count := 1
    end as CNT
  from Logs, (select @currnet := null,@count := 0) as t
) as temp
where temp.CNT >= 3
  1. 最外层的 select distinct Num as ConsecutiveNums from () as temp where temp.CNT >= 3 ; 我们可以看到中间的小括号里面被派生成了一个临时表,表名叫做 temp,并且 temp 表中有两个字段分别是Num,CNT。其实Num 则是表Logs 里面的数字,CNT 则是连续出现的累积次数,最后的where temp.CNT >= 3 则是在根据要求连续出现的次数进行查询。
  2. 派生语句SELECT Num,CASE WHEN @currnet=Num THEN @count:=@count+1 WHEN (@currnet:=Num) IS NOT NULL THEN @count:=1 END AS CNT FROM LOGS,(SELECT @currnet:=NULL,@count:=NULL) AS t 包含两个部分,一个是Select 中的case when then 另一个是from 中的 (select @currnet:= null,@count := null) as t 其中select @currnet:= null,@count := null 也是一个派生表,这里通过声明两个变量@currnet, @count 并赋值为null
  3. 中间派生的表 temp 的内容如下,通过生成记录每个数字出现的次数的临时表来查询数据。

image.jpeg

下面我们通过explain 命令看下整个 SQL 的执行过程,:

201.jpg

  1. select_type中我们可以看到总共派生了两个表,跟我们上面分析的一致;
  2. ID 为 3 的派生表的内容是select @current := null,@count := 0 定义两个变量并赋值,并且 id 越大越先执行;
  3. case 语句中第一个when 中判断当前扫描到的 num 值与定义的变量是否一致,如果一致则 count 加一,不一致则进行下一个when 条件判断,并将count 赋值为 1 返回;
  4. 经过全表扫描过后,就得到了上面的中间表 temp 的内容;

不得不说,上面的方案是很完美的,不存在 ID 是否连续的问题,也不会多层自连接,而且也可以根据要求找出连续出现的次数,相对灵活。刚开始看到这个 SQL 的时候,阿粉并不清楚整个执行的过程,然后通过 explain 才渐渐明白整个执行过程, 而且对于在 SQL 中使用变量也有了一定的了解。

关于 explain 的详解,感兴趣的朋友可以去看公号之前发的文章MySQL 之 Explain 输出分析


最后说两句(求关注)

最近大家应该发现微信公众号信息流改版了吧,再也不是按照时间顺序展示了。这就对阿粉这样的坚持的原创小号主,可以说非常打击,阅读量直线下降,正反馈持续减弱。

所以看完文章,哥哥姐姐们给阿粉来个在看吧,让阿粉拥有更加大的动力,写出更好的文章,拒绝白嫖,来点正反馈呗~。

如果想在第一时间收到阿粉的文章,不被公号的信息流影响,那么可以给Java极客技术设为一个星标

最后感谢各位的阅读,才疏学浅,难免存在纰漏,如果你发现错误的地方,留言告诉阿粉,阿粉这么宠你们,肯定会改的~

最后谢谢大家支持~

最最后,重要的事再说一篇~

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
20天前
|
SQL 关系型数据库 MySQL
深入解析MySQL的EXPLAIN:指标详解与索引优化
MySQL 中的 `EXPLAIN` 语句用于分析和优化 SQL 查询,帮助你了解查询优化器的执行计划。本文详细介绍了 `EXPLAIN` 输出的各项指标,如 `id`、`select_type`、`table`、`type`、`key` 等,并提供了如何利用这些指标优化索引结构和 SQL 语句的具体方法。通过实战案例,展示了如何通过创建合适索引和调整查询语句来提升查询性能。
119 9
|
3月前
|
程序员 C语言
【C语言】LeetCode(力扣)上经典题目
【C语言】LeetCode(力扣)上经典题目
|
3月前
|
SQL 关系型数据库 MySQL
MySQL EXPLAIN该如何分析?
本文将详细介绍MySQL中`EXPLAIN`关键字的工作原理及结果字段解析,帮助优化查询性能。`EXPLAIN`可显示查询SQL的执行计划,其结果包括`id`、`select_type`、`table`等字段。通过具体示例和优化建议,帮助你理解和应用`EXPLAIN`,提升数据库查询效率。
147 0
|
4月前
|
SQL Oracle 关系型数据库
CASE WHEN 语句的语法及示例,LeetCode 题目 “确认率” 练习
本文介绍了SQL中CASE语句的两种形式和语法,并通过LeetCode题目“确认率”的SQL查询示例展示了CASE语句在实际问题中的应用,解释了如何使用CASE语句计算特定条件的比率。
|
5月前
|
算法
LeetCode第12题目整数转罗马数字
该文章介绍了 LeetCode 第 12 题整数转罗马数字的解法,通过使用 TreeMap 按照整数从大到小排序,先使用大的罗马数字表示整数,再用小的,核心是先表示完大的罗马数字,想通此点该题较简单。
LeetCode第12题目整数转罗马数字
|
5月前
|
算法 Java
LeetCode经典算法题:矩阵中省份数量经典题目+三角形最大周长java多种解法详解
LeetCode经典算法题:矩阵中省份数量经典题目+三角形最大周长java多种解法详解
60 6
|
6月前
|
SQL 关系型数据库 MySQL
mysql性能调优:EXPLAIN命令21
【7月更文挑战第21天】掌握SQL性能调优:深入解析EXPLAIN命令的神奇用法!
65 1
|
6月前
|
SQL 缓存 关系型数据库
MySQL|浅谈explain的使用
【7月更文挑战第11天】

推荐镜像

更多