时间:2021-05-24
前言
一直是想知道一条SQL语句是怎么被执行的,它执行的顺序是怎样的,然后查看总结各方资料,就有了下面这一篇文章了。
这篇笔记主要记录mysql的基础架构,一条查询语句是如何执行的。
下面话不多说了,来一起看看详细的介绍吧
比如,在我们从student表中查询一个id=2的信息
select * from student where id=2;在解释这条语句执行流程之前,我们看看mysql的基础架构。
图来自极客时间的mysql实践,该图是描述的是MySQL的逻辑架构。
连接器
我们在使用数据库之前,需要连接到数据库,连接语句是
mysql -h $ip -u $username -p $password而我们的连接器就是处理这个过程的,连接器的主要功能是负责跟客户端建立连接、获取权限、维持和管理连接,连接器在使用的过程中如果该用户的权限改变,是不会马上生效的,因为用户权限是在连接的时候读取的,只能重新连接才可以更新权限
连接器与客户端通信的协议是tcp协议的,连接以后可以使用show processlist;看到执行的连接数
同时在连接时间内超过8小时是sleep的状态会自动断开,这个是mysql默认设置,如果一直不断开,那么这个过程可以叫做一个长连接。
与之对应的有短连接,短连接是指在执行一条或几条的以后断开连接。
当不断使用长连接的时候会占用很大的内存资源,在mysql5.7以后可以使用mysql_reset_connection语句来重新初始化资源。
查询缓存
经过连接以后,就连接上数据库了,这个时候可以执行语句了。
执行语句的时候,mysql首先是去查询缓存,之前有没有执行过这样的语句,mysql会将之前执行过的语句和结果以key-value的形式存储起来(当然有一定的存储和实效时间)。如果存在缓存,则直接返回缓存的结果。
缓存的工作流程是
当然,如果这个表修改了,那么使用这个表中的所有缓存将不再有效,查询缓存值得相关条目将被清空。所以在一张被反复修改的表中进行语句缓存是不合适的,因为缓存随时都会实效,这样查询缓存的命中率就会降低很多,不是很划算。
当这个表正在写入数据,则这个表的缓存(命中缓存,缓存写入等)将会处于失效状态,在Innodb中,如果某个事务修改了这张表,则这个表的缓存在事务提交前都会处于失效状态,在这个事务提交前,这个表的相关查询都无法被缓存。
一般来说,如果是一张静态表或者是很少变化的表就可以进行缓存,这样的命中率就很高。
下面来说说缓存的使用时机,衡量打开缓存是否对系统有性能提升是一个很难的话题
分析器
在查询缓存实效或者是无缓存的时候,这个时候MySQL的server就会利用分析器来分析语句,分析器也叫解析器。
MySQL分析器由两部分组成,第一部分是用来词法分析扫描字符流,根据构词规则识别单个单词,MySQL使用Flex来生成词法扫描程序在sql/lex.h中定义了MySQL关键字和函数关键字,用两个数组存储;第二部分的功能是语法分析在词法分析的基础上将单词序列组成语法短语,最后生成语法树,提交给优化器语法分析器使用Bison,在sql/sql_yacc.yy中定义了语法规则。然后根据关系代数理论生成语法树。
上面解释分析器太官方和复杂了,其实分析器主要是用来进行“词法分析”然后知道这个数据库语句是要干嘛,代表啥意思。
这个时候如果分析器分析出这个语句有问题的时候会报错,比如ERROR 1064 (42000): You have an error in your SQL syntax
优化器
在分析器分析完了以后知道这个语句是干嘛的时候,接下来是专门用一个优化器进行语句优化,优化器的任务是发现执行SQL查询的最佳方案。大多数查询优化器,包括MySQL的查询优化器,总或多或少地在所有可能的查询评估方案中搜索最佳方案。
优化器主要是选择一个最佳的执行方案,执行方案是为了减少开销,提高执行效率。
MySQL的优化器是一个非常复杂的部件,它使用了非常多的优化策略来生成一个最优的执行计划:
随着MySQL的不断发展,优化器使用的优化策略也在不断的进化,这里仅仅介绍几个非常常用且容易理解的优化策略而已。
执行器
在分析器知道语句要干什么,优化器知道怎么做以后,下面就到了执行的阶段,执行是交给执行器的。
执行器在执行的时候首先判断该用户对该表有没有执行权限,如果没有则会返回denied之类的错误提示。
如果有权限,则会打开表继续执行。打开表的时候,执行器会根据表定义的引擎,去使用该引擎的接口。
最后执行语句得到数据返回给客户端。
总结
MySQL得到sql语句后,大概流程如下:
0.连接器负责和客户端进行通信
1.查询缓存:首先查询缓存看是否存在k-v缓存
2.解析器:负责解析和转发sql
3.预处理器:对解析后的sql树进行验证
4.优化器:得到一个执行计划
5.查询执行引擎:执行器执行语句得到数据结果集
6.将数据放回给调用端。
好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
我们知道分析MySQL语句查询性能的方法除了使用EXPLAIN输出执行计划,还可以让MySQL记录下查询超过指定时间的语句,我们将超过指定时间的SQL语句查询称
本文实例讲述了mysql存储过程之if语句用法。分享给大家供大家参考,具体如下:mysql中的IF语句允许我们根据表达式的某个条件或值结果来执行一组SQL语句,
MySQL的EXPLAIN命令用于SQL语句的查询执行计划(QEP)。这条命令的输出结果能够让我们了解MySQL优化器是如何执行SQL语句的。这条命令并没有提供
查询到效率低的SQL语句后,可以通过EXPLAIN或者DESC命令获取MySQL如何执行SELECT语句的信息,包括在SELECT语句执行过程中表如何连接和连接
本文介绍MySQL数据库中执行select查询语句,查询指定列的数据,即指定字段的数据。再来回顾一下SQL语句中的select语句的语法:Select语句的基本