01|一条SQL查询语句是如何查询的?
mysql> select * from T where id=1;
大体来说,MySQL可以分为Server层和存储引擎层
Server层包括连接器、分析器、优化器、执行器等,涵盖了MySQL的大多数核心服务功能,包括一些内置函数(时间、日期、熟悉等),所有跨存储引擎的功能都在这一层实现。
存储引擎层负责数据的存储及提取,它的架构是插件式的,用户可以在此指定存储引擎,如InnoDB、MyISAM、Memory等。现在常用的存储引擎为InnoDB,MySQL从5.5.5版本以后默认使用InnoDB作为存储引擎。
连接器
连接器的作用就是同客户端建立连接、获取权限、维持和管理连接。步骤如下:
mysql -h$ip -P$port -u$user -p
-
客户端通过TCP协议与服务端握手。
-
连接器验证输入的用户名和密码。(验证失败返回错误:”Access denied for user“)
-
当用户名和密码验证成功以后,连接器会到权限表中去查询该用户拥有的权限。(之后这个连接里面的权限判断都依赖与此次查询到的权限)
-
连接成功。(连接完成后,如果没有后续的动作,该连接就会处于一个空闲状态)
长连接:连接成功后,如果客户端持续有请求,那就一直使用该连接,同时MySQL在执行过程中临时使用的内存是管理在连接器里面的,因此有可能导致内存占用太大,OOM,导致MySQL重启。
短连接:连接成功后,每次执行完几次请求就断开连接,下次请求则重新进行连接。
查询缓存
当连接建立完成之后,就可以执行SQL语句了,首先会查询缓存,而缓存则是将SQL语句已经返回值以key-value的形式存储在内存中的,如果查询到缓存则直接返回,否则将继续安装查询步骤向下进行查询。
但是在使用MySQL的过程中,不建议使用查询缓存,当该表有更新时,就会把该表上所有的查询缓存清除,因此缓存查询效率很低。
需要注意的是,MySQL 8.0 版本直接将查询缓存的整块功能删掉了,也就是说 8.0 开始彻底没有这个功能了。
分析器
当没有命中缓存,则要开始执行SQL语句了,此时MySQL需要对SQL语句做解析。
-
词法分析:MySQL识别SQL语句中的元素分别是什么,代表什么。如通过识别”select“来分析出这是一个查询语句,识别”T“分析为这是”表名T“,识别”id“分析为这是”列名id“
-
语法分析:MySQL通过语法规则来识别该SQL语句是否满足MySQL的语法,以及识别表名、列名在表中是否存在。如果分析失败,则会返回错误”You have an error in your SQL syntax“。
优化器
当SQL语句进过分析器后,MySQL就知道该SQL语句要做什么了,此时优化器的作用就是选择合适的执行顺序以及索引的选择。如:
mysql> select * from t1 join t2 using(ID) where t1.c=10 and t2.d=20;
- 既可以先从表 t1 里面取出 c=10 的记录的 ID 值,再根据 ID 值关联到表 t2,再判断 t2 里面 d 的值是否等于 20。
- 也可以先从表 t2 里面取出 d=20 的记录的 ID 值,再根据 ID 值关联到 t1,再判断 t1 里面 c 的值是否等于 10。
执行器
当优化器给出执行方案后,SQL语句就进入到执行阶段了,此时执行器会通过第一步中查询到的权限来判断该用户是否拥有对该表执行查询的权限,如果没有则直接返回错误”ERROR 1142 (42000): SELECT command denied to user ‘b’@‘localhost’ for table ‘T’,如果权限校验通过,则通过调用该表存储引擎提供的查询接口来对表数据进行查询,最终将查询到的数据集返回给客户端。至此该查询语句结束了!