01 | 基础架构:一条SQL查询语句是如何执行的?

学习笔记:html

MySQL基本架构图

其实一条SQL的查询语句的执行并非很复杂!mysql

咱们就从最简单的一条查询语句来入手分析这个问题。 好比一条SELECT * FROM T WHERE ID=10;这样的语句它的整个执行的流程是怎么样的呢?sql

上图就是MySQL的结构图,从结构上咱们能看到MySQL的结构主要分为两层:shell

  • server层 主要包括:链接器、查询缓存、分析器、优化器、执行器等
  • 引擎层 引擎层主要是负责数据的存储和读取

链接器

链接器主要是负责链接MySQL客户端并获取权限以及维持链接状态。咱们想要执行MySQL语句以前先要链接MySQL客户端,执行语句:数据库

mysql -h $hostname -P $port -u $user -p
复制代码

执行上面语句的时候会出现如下两种状况:缓存

  • 若是用户名或者密码不正确则会出现报错ERROR 1045 (28000): Access denied for user 'test'@'localhost' (using password: NO),相信这个报错大多数用过MySQL的人都遇到过,从字面上也很好理解,访问拒绝对于test这个用户,而后程序结束。
  • 若是用户名和密码正确则会进入MySQL客户端界面。在进入以前,MySQL会根据用户名查询出该用户拥有的权限,这个链接中的全部权限校验都是依赖于以前查询的权限。

查询缓存

NOTE The query cache is deprecated as of MySQL 5.7.20, and is removed in MySQL 8.0服务器

查询缓存是指输入查询语句,MySQL会优先执行查询缓存,若是命中缓存则直接返回查询结果。在MySQL中对于每次查询的结果会有缓存,每次有对于数据库表结构或者数据的修改,缓存就会失效。若是没有命中缓存就会继续往下执行。 因此在大多数状况下缓存的命中率是很低的,除非是一张更新频率很是低的静态表,不然缓存的命中率会很是的低。MySQL官方也是在MySQL8.0中放弃了对于查询缓存的支持。因此在大多数状况下是不建议使用查询缓存的。 关于查询缓存的配置请参考官方文档操做:Query Cache Configuration架构

分析器

没有命中缓存,就要开始执行真正的执行语句了。分析器的工做主要是对输入的SQL语句作解析。 首先会作"词法分析",当你输入一窜SQL语句的时候,系统要先能识别T是一个表名,ID是字段名,WHERE和SELECT是一个MySQL的关键字...等。 作完了这些以后就会进行"语法分析",语法分析就是判断这些关键字是否合法,若是你输入的SQL语句语法不正确就是有提示,好比WHERE关键字少个W学习

SELECT * FROM T HERE ID = 10;
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 'ID = 10' at line 1
复制代码

经过以上的输出,咱们能看到语法的检测是在分析器阶段执行的,若是遇到syntax error,只须要关注use near关键字后面的部分。优化

优化器

优化器顾名思义就是对SQL语句作优化的步骤,那就有同窗有问题了,SQL语句都写好了,MySQL系统还能对其作优化?答案是:固然能。

SELECT * FROM t1 JOIN t2 ON `id` WHERE t1.a = 10 AND t2.b = 20;
复制代码

上面是一条简单的SQL语句,系统的执行顺序能够以下:

  • 能够先查询t1表中a字段等于10的数据,而后根据查询结果经过ID关联t2表,判断t2表中的b字段是否等于20。
  • 也能够先查询t2表中b字段等于20的数据,而后根据插叙结果经过ID关联到t1表,判断t1表a字段是否等于10。

还有一些是关于数据库索引的优化,这个部分比较复杂,后面会单独讲到。

执行器

当前面几个步骤完成的时候就开始进入到执行器阶段,执行器首先会作权限校验,判断当前用户是否有该SQL语句的操做权限,若是没有则会报错。

DELETE FROM t;
ERROR 1142 (42000): DELETE command denied to user 'test'@'localhost' for table 't'
复制代码

若是权限校验也经过就会真正的执行查询,查询是经过调用引擎提供的API。

引擎

引擎层是经过插件的形式存在的,存储引擎负责MySQL中数据的储存和提取。服务器经过API与储存引擎行进通讯,这些API屏蔽了不一样引擎之间的差别,使得引擎的差别对服务层没有影响。不一样的数据存储引擎之间也是不通讯的,互相之间不会影响。

相关文章
相关标签/搜索