一条SQL执行流程:
首先MySQL在建立连接完成以后,此时你若执行一条SQL语句,MySQL会先判断你的语句是SELECT,UPDATE,INSERT,DELETE操作。
以SELECT操作语句为例:
1.先判断MySQL是否开启了查询缓存
注:查询缓存:是以SQL语句作为记录,然后记录对应的数据。
若开启了查询缓存 :
则MySQL会以SQL语句这个字符串(可以理解为SQL语句作为key然后对应的data(数据)做为value),来进行缓存。
例:"select * from user where id =1" => data(此条SQL对应的数据)。
缺点:如上所示上面那条SQL在判断查询缓存的时候 若你再次执行一样的SQL语句的话 可能会因为某部分多了一个空格或者大小写问题,而导致了MySQL查询缓存的失效。
例:select * from user where id =1和select * from user where id = 1对于查询缓存的判断是不一样的数据库会因为一个空格从而导致重新去查询数据库之前的查询缓存反而未击中。
若查询缓存中的SQL语句完全匹配,则检查权限,然后从查询缓存中返回对应的数据。(SQL执行完毕)
若查询缓存中的SQL语句不匹配则继续走下面流程,进行查询获取数据。
命令解析器:
综上所述,若查询缓存没有命中或未开启,则SQL语句会走到命令解析器进行解析通过解析器生成解析树结果返回给优化器。
解析器执行流程:
以此条SQL为例:select id,name,count(*) from user where age > 10 and name = xxx
解析器主要分两个模块:句法扫描器和语法规则模块。
句法扫描器:
句法扫描器会将整条SQL分解为令牌(可以理解为令牌 这种令牌由一些不可分割元素 如列名等 会将每一个传入的符号当作标识)
如上SQL会被分解为:
select
id
,
name
,
count
(
*
)
from
user
where
age
>
10
and
name
=
xxx
整体流程:句法扫描器 => 分解令牌 (每一个字节流都会被分解) => 分解成令牌。
语法规则模块:
语法规则模块会根据SQL语句分解出来的令牌根据关键词把令牌解析生成解析树
解析树(略)........
优化器:
综上,在SQL语句通过解析器生成解析数以后会传递给优化器,优化器会对where条件进行从新排序。
优化器执行流程:
1.优化器会根据查询条件所选择的字段进行分析 分析使用哪个键的查询效率比较高。
2.针对表进行扫描表的结构(并非表数据相当于执行了 desc table_name 若有很多得记录和键进行匹配比对的话则速度可能会相应的降低)。
3.根据顺序的查找 寻找合适的执行计划。
4.1.选择表的连接顺序 (join)。
4.2.对于where条件的重写,删除不必要的代码,减少不必要的计算量,尽可能的限制条件,方便有效键的执行(可以理解为索引)。
5.1.删除不需要连接的数据表 (join)。
5.2.确定键(索引)是否可以用于分组或者排序上。
6.1.合并大的视图 (join)。
6.2.执行通过优化器选择后的计划。
注:存储过程是预编译的,即事先通过了解析器和优化器所以在使用存储过程的时候是不会再次经过解析器和优化器的。
返回对应的数据:
一条SQL执行完以上步骤以后则进行用户权限校验若通过则调用存储引擎接口查询然后返回数据。