一条SQL查询语句是如何执行的?

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 比较喜欢的一段话:不经一番寒彻骨,怎得梅花扑鼻香,学习是枯燥的请大家坚持! 这篇文章的是向丁奇老师学习的。不懂的自己搜一下哈!

预热


比较喜欢的一段话:不经一番寒彻骨,怎得梅花扑鼻香,学习是枯燥的请大家坚持! 这篇文章的是向丁奇老师学习的。不懂的自己搜一下哈!阅读这篇文章大概需要20分钟!


大家好,我是一位农民工(码农),也是一位打算冲击一线互联网大厂的码农。目前从事的是Java后端开发,写作分享经验是我的兴趣,我想帮助更多未来可期但是现在迷茫的人!

欢迎大家来到走向一线大厂的大门!开局前,先上几句SQL大家先热热身!


explain SELECT ID FROM t_apimonitoring

explain SELECT * FROM t_apimonitoring

explain SELECT ID FROM t_apimonitoring where ID=20

explain SELECT * FROM t_apimonitoring where ID>7000


大概就是这四句啦,都是比较基础的。分别是查询性能监控表的所有数据,查询所有ID数据,查询ID为20的数据,查询ID大于7000的所有数据。最后再一一论证是如何查询的!


工作大概半年了,我见过很多同事打开SQL面板,很大的概率是非常熟练的先输入了一遍select * from 表名然后一堆数据就出来了。以及去年大厂热点话题 <谁在写select * 给我滚蛋>。大家有没有想过为什么会这样呢?


开始


image.png

首先MySQL大体可以分为,Service层,存储引擎层两个部分。

连接器: 校验用户身份信息,校验当前用户的SQL语句权限,管理SQL连接的通道

分析器: 词法分析,语法分析。用于处理客户端的SQL语句,分析处理完之后写入缓存,如果下次命中的话直接返回提高查询效率。

优化器: 生成执行计划,索引选择(这里可以完美解释我上面抛出的SQL执行问题)

执行器: 调用操作存储引擎,捞取数据。

存储引擎: 后面会详细讲一些扩展引擎,第三方引擎,大数据量引擎等。这里会简单介绍一下Innodb与myisam


连接器

  1. 通过这个指令建立连接 mysql -h 127.0.0.1 -P 3306 -u root -p 123456
  2. 通过分配后的权限,每个用户可以操作相应的事情

image.png

  1. 建立连接之后可以通过 show processlist 查询连接状态。其中的 Command 列显示为“Sleep”的这一行,就表示现在系统里面有一个空闲连接。客户端如果太长时间没动静,连接器就会自动将它断开。这个时间是由参数 wait_timeout 控制的,默认值是 8 小时。

image.png

4.数据库连接又分为两种连接方式,一种是长连接,一种是短连接。长连接的意思就是建立连接之后,如果客户端的有请求操作则一种使用同一个连接进行交互处理。短连接的意思就是建立连接之后,并且客户端执行完自己的需求之后,就关闭了连接。

结论: 数据库建立连接这个过程是比较复杂的,所以建立尽量减少使用短连接的方式,也就是尽量使用长连接

弊端: 全部使用长连接后,你可能会发现,有些时候 MySQL 占用内存涨得特别快,这是因为 MySQL 在执行过程中临时使用的内存是管理在连接对象里面的。这些资源会在连接断开的时候才释放。所以如果长连接累积下来,可能导致内存占用太大,被系统强行杀掉(OOM),从现象看就是 MySQL 异常重启了。怎么解决这个问题呢?你可以考虑以下两种方案。定期断开长连接。使用一段时间,或者程序里面判断执行过一个占用内存的大查询后,断开连接,之后要查询再重连。如果你用的是 MySQL 5.7 或更新版本,可以在每次执行一个比较大的操作后,通过执行 mysql_reset_connection 来重新初始化连接资源。这个过程不需要重连和重新做权限验证,但是会将连接恢复到刚刚创建完时的状态。


查询缓存

建立连接之后,就可以开始我们的操作了,比如写一些SQL语句了。MySQL拿到一个SQL请求后,会先检查缓存中是否已经执行过这条语句了,如果当前存在就直接返回这是最有的查询方式,效率也是非常高的,但是在实践中往往不建议使用缓存,因为缓存内有一个机制,当这个表发生更新的时候就会清空缓存,在真正的操作中一般都会多次更新操作的。所以就算存了缓存也用不上,除非有一些系统设置表,用户表等一些冷门的表才建议使用缓存。

使用手法:将参数query_cache_type设置成DEMAND,这样对于默认的SQL都不使用查询缓存,而真正对于一些系统设置类的静态表可以在SQL上添加以下指令实现缓存效率。

mysql> select SQL_CACHE * from T where ID=10;


分析器

分析器要做的事情主要是‘词法分析’和‘语法分析’

如果没有命中缓存就说明走到这一步了.我们看到的一串字符串,真正在执行的时候不会执行一段字符串的,所以分析器的作用就是提取字符串的指令,比如开头的SQL指令。字符串select会转换成一个查询语句,字符串t_apimonitoring会转换成表t_apimonitoring,字符串ID会转换成列ID。

转换成SQL语言之后就开始进行语法分析了,分析SQL语法是否有错误,如果没有错误的话下一步继续执行,如果有错误的话我们只需要关注use near大概就能解决一切了,所以SQL还是非常强大方便的。> 1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'from where ss per_user' at line 1


优化器

经过分析器已经转一个字符串转换成一个SQL语句了。优化器所要做的事情就是,寻找匹配索引达到最优查询效率。 这里是t1表跟t2表进行关联,查询t1表中的c字段为10的数据并且也查询t2表中的d字段为20的共同数据。如果换一个说法这里是t2表跟t1表进行关联,查询t2表中的d字段为20的数据并且查询t1表中的c字段为10的数据的共同数据。这两个说法都是对的。但是对于SQL来说,寻找不同的索引能极大的提高性能。

mysql> select * from t1 join t2 using(ID)  where t1.c=10 and t2.d=20;


执行器

分析器处理了要做什么,优化器处理了要怎么做,最后可以执行SQL语句了。在执行SQL的时候会有一步procheck验证权限的步骤,这一步我估计会有很多人会比较懵,一开始连接不也是校验权限吗。其实这两步的权限是不一样的。一开始是校验用户的大权限,执行器这里验证的是用户中对每个表的操作权限。如果有就开始调用引擎接口,如果没有就返回权限错误。

以下列SQL为例,执行SQL的步骤就是会先捞取表中的第一条数据,并且判断ID是不是为10,如果不是就跳过,继续重复操作一直找到ID为10的数据为止然后返回结果集给客户端

mysql> select * from T where ID=10;

你会在数据库的慢查询日志中看到一个 rows_examined 的字段,表示这个语句执行过程中扫描了多少行。这个值就是在执行器每次调用引擎获取数据行的时候累加的。在有些场景下,执行器调用一次,在引擎内部则扫描了多行,因此引擎扫描行数跟 rows_examined 并不是完全相同的。我们后面会专门有一篇文章来讲存储引擎的内部机制,里面会有详细的说明。


结尾


感谢各位小伙伴看完这篇文章,这篇文章大概介绍了一下SQL的运行过程。是不是又自信了一点呢?


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
11天前
|
SQL 监控 关系型数据库
SQL语句当前及历史信息查询-performance schema的使用
本文介绍了如何使用MySQL的Performance Schema来获取SQL语句的当前和历史执行信息。Performance Schema默认在MySQL 8.0中启用,可以通过查询相关表来获取详细的SQL执行信息,包括当前执行的SQL、历史执行记录和统计汇总信息,从而快速定位和解决性能瓶颈。
|
23天前
|
SQL 存储 缓存
如何优化SQL查询性能?
【10月更文挑战第28天】如何优化SQL查询性能?
80 10
|
17天前
|
SQL 关系型数据库 MySQL
|
1月前
|
SQL 数据库 开发者
功能发布-自定义SQL查询
本期主要为大家介绍ClkLog九月上线的新功能-自定义SQL查询。
|
1月前
|
SQL 移动开发 Oracle
SQL语句实现查询连续六天数据的方法与技巧
在数据库查询中,有时需要筛选出符合特定时间连续性条件的数据记录
|
1月前
|
SQL Java 数据库连接
如何使用`DriverManager.getConnection()`连接数据库,并利用`PreparedStatement`执行参数化查询,有效防止SQL注入。
【10月更文挑战第6天】在代码与逻辑交织的世界中,我从一名数据库新手出发,通过不断探索与实践,最终成为熟练掌握JDBC的开发者。这段旅程充满挑战与惊喜,从建立数据库连接到执行SQL语句,再到理解事务管理和批处理等高级功能,每一步都让我对JDBC有了更深的认识。示例代码展示了如何使用`DriverManager.getConnection()`连接数据库,并利用`PreparedStatement`执行参数化查询,有效防止SQL注入。
101 5
|
1月前
|
SQL 数据挖掘 数据库
SQL查询每秒的数据:技巧、方法与性能优化
id="">SQL查询功能详解 SQL(Structured Query Language,结构化查询语言)是一种专门用于与数据库进行沟通和操作的语言
|
1月前
|
SQL 移动开发 大数据
SQL语句查询连续六天满足条件的记录
在数据库管理和数据分析中,我们经常需要查询符合特定时间范围内连续几天的记录
|
1月前
|
SQL 数据挖掘 关系型数据库
SQL查询次数大于1的记录:高效技巧与方法
在数据库管理中,经常需要统计某些操作的次数,特别是当需要找出哪些记录或值出现的次数超过一定阈值(如大于1次)时
|
1月前
|
SQL 存储 安全
SQL查询数据库:基础概念与操作指南
在数字化时代,数据库已成为信息管理的重要工具之一。作为管理和操作数据库的核心语言,SQL(结构化查询语言)已成为数据管理和查询的关键技能。本文将全面介绍SQL查询数据库的基本概念、语句和操作指南,以帮助初学者快速上手,同时为进阶用户提供有价值的参考。一、数据库与SQL简介数据库是一种存储、管理和检索
44 3

热门文章

最新文章

下一篇
无影云桌面