DDR爱好者之家 Design By 杰米

前言

一直是想知道一条SQL语句是怎么被执行的,它执行的顺序是怎样的,然后查看总结各方资料,就有了下面这一篇文章了。

这篇笔记主要记录mysql的基础架构,一条查询语句是如何执行的。

下面话不多说了,来一起看看详细的介绍吧

比如,在我们从student表中查询一个id=2的信息

select * from student where id=2;

在解释这条语句执行流程之前,我们看看mysql的基础架构。

mysql基础架构教程之查询语句执行的流程详解

图来自极客时间的mysql实践,该图是描述的是MySQL的逻辑架构。

  • server层包括连接器、查询缓存、分析器、优化器、执行器涵盖 MySQL 的大多数核心服务功能,以及所有的内置函数所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视等。
  • 存储引擎层负责数据的存储和提取。其架构模式是插件式的,支持InnoDB、MyISAM、Memory 等多个存储引擎,平常我们比较常用的是innoDB引擎

mysql基础架构教程之查询语句执行的流程详解

连接器

我们在使用数据库之前,需要连接到数据库,连接语句是

mysql -h $ip -u $username -p $password

而我们的连接器就是处理这个过程的,连接器的主要功能是负责跟客户端建立连接、获取权限、维持和管理连接,连接器在使用的过程中如果该用户的权限改变,是不会马上生效的,因为用户权限是在连接的时候读取的,只能重新连接才可以更新权限

连接器与客户端通信的协议是tcp协议的,连接以后可以使用show processlist;看到执行的连接数

mysql基础架构教程之查询语句执行的流程详解

同时在连接时间内超过8小时是sleep的状态会自动断开,这个是mysql默认设置,如果一直不断开,那么这个过程可以叫做一个长连接。

与之对应的有短连接,短连接是指在执行一条或几条的以后断开连接。

当不断使用长连接的时候会占用很大的内存资源,在mysql5.7以后可以使用mysql_reset_connection语句来重新初始化资源。

查询缓存

经过连接以后,就连接上数据库了,这个时候可以执行语句了。

执行语句的时候,mysql首先是去查询缓存,之前有没有执行过这样的语句,mysql会将之前执行过的语句和结果以key-value的形式存储起来(当然有一定的存储和实效时间)。如果存在缓存,则直接返回缓存的结果。

缓存的工作流程是

  • 服务器接收SQL,以SQL和一些其他条件为key查找缓存表
  • 如果找到了缓存,则直接返回缓存
  • 如果没有找到缓存,则执行SQL查询,包括原来的SQL解析,优化等。
  • 执行完SQL查询结果以后,将SQL查询结果缓存入缓存表

当然,如果这个表修改了,那么使用这个表中的所有缓存将不再有效,查询缓存值得相关条目将被清空。所以在一张被反复修改的表中进行语句缓存是不合适的,因为缓存随时都会实效,这样查询缓存的命中率就会降低很多,不是很划算。

当这个表正在写入数据,则这个表的缓存(命中缓存,缓存写入等)将会处于失效状态,在Innodb中,如果某个事务修改了这张表,则这个表的缓存在事务提交前都会处于失效状态,在这个事务提交前,这个表的相关查询都无法被缓存。

一般来说,如果是一张静态表或者是很少变化的表就可以进行缓存,这样的命中率就很高。

下面来说说缓存的使用时机,衡量打开缓存是否对系统有性能提升是一个很难的话题

  • 通过缓存命中率判断, 缓存命中率 = 缓存命中次数 (Qcache_hits) / 查询次数 (Com_select)
  • 通过缓存写入率, 写入率 = 缓存写入次数 (Qcache_inserts) / 查询次数 (Qcache_inserts)
  • 通过 命中-写入率 判断, 比率 = 命中次数 (Qcache_hits) / 写入次数 (Qcache_inserts), 高性能MySQL中称之为比较能反映性能提升的指数,一般来说达到3:1则算是查询缓存有效,而最好能够达到10:1

分析器

在查询缓存实效或者是无缓存的时候,这个时候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的优化器是一个非常复杂的部件,它使用了非常多的优化策略来生成一个最优的执行计划:

  • 重新定义表的关联顺序(多张表关联查询时,并不一定按照SQL中指定的顺序进行,但有一些技巧可以指定关联顺序)
  • 优化MIN()和MAX()函数(找某列的最小值,如果该列有索引,只需要查找B+Tree索引最左端,反之则可以找到最大值,具体原理见下文)
  • 提前终止查询(比如:使用Limit时,查找到满足数量的结果集后会立即终止查询)
  • 优化排序(在老版本MySQL会使用两次传输排序,即先读取行指针和需要排序的字段在内存中对其排序,然后再根据排序结果去读取数据行,而新版本采用的是单次传输排序,也就是一次读取所有的数据行,然后根据给定的列排序。对于I/O密集型应用,效率会高很多)

随着MySQL的不断发展,优化器使用的优化策略也在不断的进化,这里仅仅介绍几个非常常用且容易理解的优化策略而已。

执行器

在分析器知道语句要干什么,优化器知道怎么做以后,下面就到了执行的阶段,执行是交给执行器的。

执行器在执行的时候首先判断该用户对该表有没有执行权限,如果没有则会返回denied之类的错误提示。

如果有权限,则会打开表继续执行。打开表的时候,执行器会根据表定义的引擎,去使用该引擎的接口。

最后执行语句得到数据返回给客户端。

总结

MySQL得到sql语句后,大概流程如下:

0.连接器负责和客户端进行通信

1.查询缓存:首先查询缓存看是否存在k-v缓存

2.解析器:负责解析和转发sql

3.预处理器:对解析后的sql树进行验证

4.优化器:得到一个执行计划

5.查询执行引擎:执行器执行语句得到数据结果集

6.将数据放回给调用端。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。

DDR爱好者之家 Design By 杰米
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
DDR爱好者之家 Design By 杰米

《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线

暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。

艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。

《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。