一条查询语句的执行过程

在分析一条sql查询语句之前,我们先看一下MySql的体系结构,介绍一下它的组成部分,然后在结合查询语句,分析过程及各组件的作用。

由上图可知,MySql大体有两部分组成,server、存储引擎及物理文件。server层包括连接器、缓存、分析器、优化器;存储引擎是插件式,可插拔的,如InnoDB,MyISAM,Memory等;物理文件包括数据文件及日志等。

下面结合mysql> select * from T where ID=10;这条查询语句分析过程。

  1. 建立连接。这时候发挥作用的是连接器,它负责跟客户端建立连接,验证权限,维持和管理连接。连接MySql操作是一个连接进程和MySql数据库实例进行通信的过程,本质上是进程间的通信,如TCP/IP,socket套接字(仅可用于数据库和实例在一台机器上)等。

    使用用TCP/IP连接:mysql -h$ip -P$port -u$user -p

    mysql会查一张权限表,用来判断发起连接的IP是否允许连接到mysql实例

    然后验证用户名和密码是否匹配,如果用户名或密码不对,就会收到一个”Access denied for user“的错误

    如果用户名和密码验证通过,连接器就会查出你对这张表所拥有的权限。之后,这个连接里面的权限判断逻辑,都将依赖于此时读到的权限。如果用管理员账号对权限做出了修改,也不会影响到现有权限;修改完成后,只有重新建立连接,才可以取到修改后的权限。

  2. 查询缓存。建立连接后,就执行查询语句,先去查缓存,看缓存中有没有执行过该条语句。缓存会以key-value的形式缓存查询语句及其结果,若查不到缓存,再执行后面的过程。

    大多数的情况下,使用缓存弊大于利,因为每当表更新时,这张表的缓存就会消失了,也就是缓存失效非常频繁,除非是不经常变动的配置表。

  3. 分析器:词法分析和语法分析。分析器首先会对select * from T where ID=10 进行词法分析,它会识别select为查询语句,T为表名,ID为列名;然后做语法分析,如果这条sql语句写的不正确,会收到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 'xxx'

  4. 优化器:在表里有多个索引的时候,优化器会决定使用哪个索引;在多个表进行关联的时候,决定它们的连接顺序;

    select * from t1 join t2 using(ID) where t1.c=10 and t2.d=20;,既可以从表t1里面取出c=10的记录的ID值,再根据ID值关联到表t2,再判断t2里面的值是否等于20;也可以从表t2里面取出d=20的记录的ID值,再根据ID值关联到t1,再判断t1里面的c的值是否等于10.

    两种执行方法最终得到的结果一样,但是执行效率会有所不同,优化器决定使用哪一个方案

  5. 执行器。执行sql语句,在开始执行前,先判断对这张表有无查询权限;如果没有返回权限的错误,如ERROR 1142 (42000): SELECT command denied to user 'b'@'localhost' for table 'T';如果有权限的话,就会打开表,取表中第一行,判断id是否为10,不是的话,继续下一行;是的话,保存在结果集中,最后返回给客户端