俯瞰Mysql:一条SQL语句是如何执行的!

2019-03-12  本文已影响0人  yes的练级攻略

对于绝大部分开发同学来说,用Mysql反正就是写出了一条正确的SQL,执行了之后结果返回就OK了。我们不会太关注这条语句具体经历过啥,也没有关注过mysql具体是如何执行这条语句的!

虽说平日里其实不了解这些内部机制问题不大,但是如果你了解了这些,当你遇到Mysql的一些异常或者问题时,你就能够快速的定位和解决问题!这点就能让你在绝大部分的开发中脱颖而出! 尽显大神风范哈哈哈!

来咱们先解剖一下Mysql,看看它到底有哪些功能模块

Mysql解剖图

Mysql分为两大层,分别为Server层和存储引擎层。

Server层几乎涵盖了Mysql的核心服务功能,包括一些内置函数、存储过程、视图等等,这些都在Server层。

存储引擎层主要是提供数据的读写接口和数据的存储。它是插件式的,啥意思呢?就是支持多种引擎,任君挑选:例如MyISAM、InnoDB、Memory等。从5.5.5版本开始InnoDB成为了默认存储引擎。

咱们一步一步来看看整个执行流程:

第一步:连接器

首先你需要连接到数据库上,你会输入ip,端口,账号密码。然后根据你的账号密码,连接器就来验证你的身份了。

两种情况:1.用户密码不对,你就被Access denied了。

                  2.验证通过,连接器就去权限表获取这个账户下面的权限用于这个连接之后的权限判断。

第二种情况的意思就是,如果这个连接还保持着,如果管理员更改了你账户的权限,不会影响你的账户。只有断开了连接再重新连接才会有影响。而且这个连接如果你连你之后一直没啥操作,连接器就会自动断开连接,默认时间是8小时。

这里有一点要注意:你的所有操作的临时内存都会保存在你这个连接里面,只有在断开连接之后才会释放这些内存。所以如果长时间保持连接,并且有大内存的操作导致占用内存太多了,Mysql就会被系统重启了。

所以如果有大内存操作最好重连一下释放临时内存!如果你Mysql版本是5.7或者以上的,可以通过执行mysql_reset_connection来释放临时内存。

第二步:查缓存

连接好之后如果你执行查询语句就会先去缓存看看,如果之前执行过这条语句的话,会以键值对的形式保存在缓存中,key就是查询语句,value就是结果,能直接返回。

听起来好像很好,缓存了之后很舒服,但是往往利用缓存弊大于利!怎么说?

比如你对一个表查了10条语句,好了都缓存了,如果这个表的一个update语句进来,完了。之前所有缓存都会被清空!白忙了!除非是静态表,基本上不会有更新的那种,可以用缓存!

注意8.0版本直接把缓存咔了,没这个功能了。

第三步:分析器

如果缓存没中,好了就来到了分析器了,先分析下词法,例如"select"这样的关键字还有你的表名,列名提取出来,然后再语法分析,判断你的语句是否满足语法,如果不对那就给你个"You have an error in your SQL syntax" 是不是常见?

第四步:优化器

分析了之后其实Mysql已经知道你要干嘛了,但是它还是要帮你优化一下!比如决定用哪个索引啊?怎么个顺序连接表啊等。

举个例子 "select * from a join b on a.id = b.id where a.t=10 and b.e=20;"

第一种情况,先从表a中找出t=10的值,再根据这些id关联表b,再判断e是否等于20。

第二种情况,先从表b中找出e=20的值,再根据这些id关联表a,再判断t是否等于10。

这两种结果肯定都是一样的,但是根据表a和表b的数据执行效率是不一样的,由优化器来预估决定到底用哪种方案!优化器就是干这事的!

第五步:执行器

到这步就来执行了!执行时候来看看你有没有这个权限,有的话就继续执行,没的话你懂得,就是command denied了!

按照上面那个语句,如果用了第一种情况,那执行流程就是:

通过存储引擎的接口调用引擎返回表的第一行,看看t是不是10,如果是则存入结果集,如果不是则跳过。

继续调接口取第二行直到遍历完,

然后返回结果集给客户端。

可能会有人觉得奇怪,为什么在第五步的时候才验证权限?为什么不在优化器之前做?

因为在有时SQL语句操作的不仅仅是SQL字面上这些的,比如你搞了个触发器,触发器只有在执行的时候才能确认,所以验证权限这步得在执行器做,之前的做不了。

一条语句在Mysql的执行就这样大功告成了!

上一篇下一篇

猜你喜欢

热点阅读