一、MySQL逻辑结构
MySQL 可以分为 Server 层和存储引擎层两部分。
二、sql的执行流程
1、连接器
在数据库层执行SQL语句时,应用程序会连接到相应的数据库服务器,把SQL语句发送给服务器处理。
2、查询缓存
服务器在解析一个查询语句之前,如果查询缓存是打开的(MySQL默认打开,可以使用have_query_cache查看),在接收到查询请求后,并不会直接去数据库查询,而是在数据库的查询缓存中找是否有相对应的查询数据(某条给定的查询语句在第一次执行时,服务器会缓存这条查询语句和他返回的结果。),如果存在,那么在返回查询结果之前,MySQL会检查一次用户权限。如果权限没有问题,key 是查询的语句,value 是查询的结果。如果你的查询能够直接在这个缓存中找到 key,那么这个 value 就会被直接从缓存中拿到结果返回给客户端。
需要注意的是,MySQL 8.0版本直接将查询缓存的整块功能删掉了,也就是说8.0开始彻底没有这个功能了。
3、分析器
如果没有命中查询缓存,就要开始真正执行语句了。
分析器将SQL语句进行解析,并生成一棵对应的解析树。分析器主要做以下两件事:
1.词法分析
解析sql语句,比如从select关键字识别这是一个查询语句,将"T"识别成"表名T",把"ID"识别成"列ID"
2.语法分析
根据语法规则,判断你的sql是否满足mysql语法
4、优化器
优化器是在表里面有多个索引的时候,决定使用哪个索引;或者在一个语句有多表关联(join)的时候,决定各个表的连接顺序,将SQL语句转化成执行计划,一条查询可以有很多种执行方式,最后都返回相同的结果,最后找到其中最好的执行计划(Mysql使用基于成本的优化器,它将尝试预测一个查询使用某种执行计划的成本,选择其中成本最小的一个)。
5、执行器
MySQL通过分析器知道了你要做什么,通过优化器知道了该怎么做,于是就进入了执行器阶段,开始执行语句。
以sql:select * from user where ID=10;
为例,
开始执行的时候,要先判断一下你对这个表user有没有执行查询的权限,如果没有,就会返回没有权限的错误,如下所示(在工程实现上,如果命中查询缓存,会在查询缓存放回结果的时候,做权限验证。查询也会在优化器之前调用precheck验证权限)。
ERROR 1142 (42000): SELECT command denied to user 'b'@'localhost' for table 'user'
如果有权限,就打开表继续执行。打开表的时候,执行器就会根据表的引擎定义,去使用这个引擎提供的接口。 如果ID字段没用索引,那么执行流程是这样的:
1.调用InnoDB引擎接口取user表的第一行,判断ID值是不是10,如果不是则跳过,如果是则将这行存在结果集中;
2.调用引擎接口取“下一行”,重复相同的判断逻辑,直到取到这个user的最后一行。
3.执行器将上述遍历过程中所有满足条件的行组成的记录集作为结果集返回给客户端。
对于有索引的表,执行的逻辑也差不多。第一次调用的是“取满足条件的第一行”这个接口,之后循环取“满足条件的下一行”这个接口,这些接口都是引擎中已经定义好的。
如果查询可以缓存,Mysql在这个阶段也会将结果放到查询缓存中。