MySql基础架构(sql查询语句在MySql内部具体是怎么执行的?)

 
 

提出问题:

对于一个做后台不久的我,起初做项目只是实现了功能,所谓的增删改查,和基本查询索引的建立。直到有一个面试官问我一个问题,一条sql查询语句在mysql数据库中具体是怎么执行的?我被虐了,很开心,感谢他。于是开始了深入学习mysql。本篇文章通过

一条sql查询语句在mysql数据库中具体是怎么执行的?

来具体讲解mysql的基础架构。

讲解

mysql> select * from Student where ID=1;

上面一条简单的查询语句很简单,但我想好多开发者并不知道在MYSQL内部的执行过程。

Mysql基本架构示意图

640?wx_fmt=png

Mysql基本架构示意图。 从图中可以看出Mysql可以大体分为Server层和存储引擎层两部分。

Server层包括连接器、查询缓存、分析器、优化器、执行器等,这些涵盖了MySQL的大多数核心服务和所有的内置函数(如日期、时间、数学和加密函数等),跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图等。

存储引擎层负责数据的存储和提取,提供数据的读写接口。其架构模式是插件式的,支持InnoDB、MyISAM、Memory等多个存储引擎。目前开发中最常用的存储引擎是InnoDB,它从MySQL5.5.5版本开始成为默认存储引擎,不过开发者也可以通过指定存储引擎的类型来选择别的引擎。

即使存储引擎不同,但是也会共用一个Server层,接下来对Server层中的执行流程,依次对其作用进行讲解。

连接器

运行查询语句开始查询的前提是第一步先连接数据库,这时候等待你的就是连接器。连接器负责和客户端建立连接、获取权限、维持和管理连接。

常规的开发模式,客户端与服务器需要建立连接。二者在完成经典的TCP握手后,Server层连接器就要开始认证你的身份,这个时候是服务器端代码使用的用户名和密码。

连接器一些内容说明:

 
 
mysql>show processlist

较好的连接方式长连接产生的问题以及解决办法:

全部使用长连接后,你可能会发现,有些时候 MySQL 占用内存涨得特别快,这是因为 MySQL 在执行过程中临时使用的内存是管理在连接对象里面的。这些资源会在连接断开的时候才释放。所以如果长连接累积下来,可能导致内存占用太大,被系统强行杀掉(OOM),从现象看就是 MySQL 异常重启了。怎么解决这个问题呢?你可以考虑以下两种方案。

  1. 定期断开长连接。使用一段时间,或者程序里面判断执行过一个占用内存的大查询后,断开连接,之后要查询再重连。

  2. 如果你用的是 MySQL 5.7 或更新版本,可以在每次执行一个比较大的操作后,通过执行 mysql_reset_connection 来重新初始化连接资源。这个过程不需要重连和重新做权限验证,但是会将连接恢复到刚刚创建完时的状

查询缓存

第一步连接建立完成后,就可以执行查询语句了。第二部:查询缓存。 Mysql确定了查询语句,会先到查询缓存中,看之前是否执行过这条查询语句。之前如果执行过这条查询语句,查询结果可能会以key-value的方式直接缓存在内存中。key是查询的语句,value是查询到的值,这样的话查询缓存会直接把value值返回给客户端。查询语句如果步子查询缓存中,会正常往下执行,获取到新的查询结果后会被存入到查询缓存中。

说明:

  1. ounter(line

  2. ounter(line

注意:

Mysql 8.0版本直接将查询缓存对整块功能删除掉了,8.0之后将不再出现查询缓存。

分析器

如果在查询缓存中未找到缓存数据,就会开始真正的执行查询语句。Mysql需要直到这条查询语句要做什么?因此需要对SQL语句做解析。

解析流程:

  1. ounter(line

语法分析

词法分析后,语句法分析会根据语法规则,判断输入的SQL语句是否满足MySql语法。如果语法不对,会收到“You have an error in your SQL syntax”的错误提醒。例如

 
 
mysql> elect * from Student where ID=1;	
	
ERROR 1064 (42000) 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 'elect * from t where ID=1' at line 1

技巧:一般语法错误看错误提示的时候,要关注的是紧接“use near”的内容

  1. ounter(line

  2. ounter(line

  3. ounter(line

优化器

分析器执行之后,到达了优化器。

优化器会做那些优化处理:

  1. 该例子既可以先从表t1里面取出c=10的记录的ID值,再根据ID值关联到表t2,再判断t2里面d的值是否等于20.

  2. 也可以先从表 t2 里面取出 d=20 的记录的 ID 值,再根据 ID 值关联到 t1,再判断 t1 里面 c 的值是否等于 10。

  1. ounter(line

执行器

MySQL 通过分析器知道了你要做什么,通过优化器知道了该怎么做(执行方案是什么?),于是就进入了执行器阶段,开始执行语句。

开始执行的时候,要先判断一下你对这个表 Student 有没有执行查询的权限,如果没有,就会返回没有权限的错误,如下所示 (在工程实现上,如果命中查询缓存,会在查询缓存返回结果的时候,做权限验证。查询也会在优化器之前调用 precheck 验证权限)。

 
 
mysql> select * from Student where ID=10;	
 	
ERROR 1142 (42000): SELECT command denied to user 'b'@'localhost' for table 'Student'

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

存储引擎

来到存储引擎,执行存储引擎提供的数据读写接口。 这条查询语句,存储引擎读写数据的流程要分两种情况考虑:

总结

到此,一条查询语句在mysql架构中执行基本流程进行了一个大概的讲解。在这个流程中,会有很多细节和可深挖学习的地方,例如关联(join)、索引等,接下来会继续学习并记录一些MySql深入的东西。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值