赞
踩
MySQL 架构可以分为 Server 层、存储引擎两部分。如下图所示:
从图中可以看出:
Server 层包括连接器、查询缓存、分析器、优化器、执行器。包含所有内置函数,所有跨存储引擎的功能都在这里实现,如存储过程、视图、触发器等。
存储引擎层负责数据的存储和提取。常见的存储引擎:MyISAM、InnoDB、Memory。
接下来我们就来看看一条查询语句是如何执行的。以下面这个 SQL 语句为例:
select * from t where id = 1;
首先我们要登录 MySQL,输入登录命令 mysql -uroot -p
,通过 TCP 三次握手来跟服务端建立连接,此时,连接器就开始校验输入的用户名与密码。
Access denied for user
的错误,然后客户端程序结束执行若客户端长时间没有操作则会断开连接,由参数 wait_timeout 控制,默认为 8 小时。在连接断开之后,如果客户端再次发送请求的话,就会收到一个错误提醒: Lost connection to MySQL server during query
。
连接建立后,可以使用查询语句了。
此时,来到第二步:查询缓存。
之前执行过的语句及其结果可能会以 key-value对 的形式,被直接缓存在内存中。key 是查询的语句,value 是查询的结果。如果查询语句能够直接在这个缓存中找到key,那么就会直接返回给客户端对应的 value,不需要在往后执行了。
但是,缓存的缺点在于:只要有对一个表的更新,这个表上所有的查询缓存都会被清空。 所以,对于频繁更新的表来说,查询缓存的效率非常低,这时使用查询缓存就有点得不偿失了。
可以将参数 query_cache_type
设置成 DEMAND
,这样对于默认的SQL语句都不使用查询缓存。而对于确定要使用查询缓存的语句,可以用 SQL_CACHE 来显式的指定,如 select SQL_CACHE * from t where id=1;
在 MySQL 8.0 版本之后就没有查询缓存这个功能了。
来到第三步:分析器。
分析器会对 SQL 语句进行词法分析,识别出里面的字符串分别是什么,代表什么。
MySQL 把输入的 select 这个关键字识别出来,这是一个查询语句。它也要把字符串“t”识别成“表名t”,把字符串“id”识别成“列id”。
然后分析器会对 SQL 语句做语法分析。分析器根据语法规则,判断这个 SQL 语句是否满足 MySQL 的语法规则。若是语法不正确,会返回 You have an error in your SQL syntax
的错误。
接下来来到第四步:优化器。
优化器的作用是在表里面有多个索引时,决定使用哪个索引;或者在一个语句有多表关联,即使用 join 的时候,决定各个表的连接顺序。优化器阶段完成后,这个语句的执行方案就确定下来了。
然后进入第五步:执行器。
在开始执行的时候,要先判断一下这个登录用户对这个表 t 有没有执行查询的权限,如果没有,就会返回没有权限的错误。如果是语句命中了查询缓存,会在查询缓存返回结果的时候,做权限验证。
如果有权限,就会继续执行语句。找到对应的表并打开表,执行器就会根据表的引擎去使用这个引擎提供的接口。
比如这个例子中的表 t 中,id 字段没有索引,使用的引擎是 InnoDB,那么执行器的执行流程是这样的:
至此,这个语句就执行完成了。
若是有索引的情况。第一次调用的是“取满足条件的第一行”这个接口,之后循环取“满足条件的下一行”这个接口,这些接口都是引擎中已经定义好的。
根据上面的介绍,SQL 语句总体的执行顺序:连接器 -> (查询缓存)-> 分析器 -> 优化器 -> 执行器。
下面是一条查询语句执行过程的流程图:
总结:
《MySQL 必知必会》
《MySQL 45讲》
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。