深刻学习MySQL,从概览MySQL逻辑架构开始。mysql
首先来看一下MySQL的逻辑架构图:sql
MySQL逻辑架构大概能够分为三层:数据库
值得一提的是在MySQL8.0中取消了查询缓存,大概的理由是查询缓存存在严重的可伸缩性问题,而且很容易成为严重的瓶颈缓存,将缓存移动到客户端能收获更好的性能。缓存
经过一条查询语句的执行过程,来了解一些关键的部件:安全
mysql> select * from T where ID=10;
首先,须要链接数据库。服务器
当客户端(应用)链接到MySQL服务器时,服务器须要对其进行认证。认证基于用户名、原始主机信息和密码。网络
链接命令:架构
mysql -h$ip -P$port -u$user -p
除了基本认证以外,链接器还会进行一些线程的处理。函数
每一个客户端链接都会在服务器进程中拥有一个线程,这个链接的查询只会在这个单独的线程中执行,该线程只能轮流在某个CPU核心或者CPU中运行。服务器会负责缓存线程,所以不须要为每个新建的链接建立或者销毁线程。工具
对于SELECT语句,在解析查询以前,服务器会先检查查询缓存(Query Cache),若是可以在其中找到对应的查询,服务器就没必要再执行查询解析、优化和执行的整个过程,而是直接返回查询缓存中的结果集。
但不推荐使用查询缓存,为何呢?由于查询缓存每每弊大于利。
查询缓存的失效很是频繁,只要有对一个表的更新,这个表上全部的查询缓存都会被清空。对于更新压力大的数据库来讲,查询缓存的命中率会很是低。除非你的业务就是有一张静态表,很长时间才会更新一次。好比,一个系统配置表,那这张表上的查询才适合使用查询缓存。
好在MySQL也提供了这种“按需使用”的方式。能够将参数query_cache_type设置成DEMAND,这样对于默认的SQL语句都不使用查询缓存。而对于肯定要使用查询缓存的语句,能够用SQL_CACHE显式指定,以下:
mysql> select SQL_CACHE * from T where ID=10;
上面也提到了MySQL8.0完全废弃了查询缓存的功能。
若是缓存没有命中的话,MySQL会对查询语句进行解析。简单说解析的做用将咱们人能看懂的SQL解析成MySQ能识别的语言。
解析器先会作“词法解析”。输入的是由多个字符串和空格组成的一条SQL语句,MySQL须要识别出里面的字符串分别是什么,表明什么。
MySQL从输入的"select"这个关键字识别出来,这是一个查询语句。它也要把字符串“T”识别成“表名T”,把字符串“ID”识别成“列ID”。
作完了这些识别之后,就要作“语法解析”。根据词法解析的结果,语法解析器会根据语法规则,判断输入的这个SQL语句是否知足MySQL语法。
通过了解析器器,MySQL知道咱们要干什么。
接下来并非直接执行,而是会在优化器这一层进行优化,优化器是个很是复杂的部件,它会帮我去使用他本身认为的最好的方式去优化这条 SQL 语句,并生成一条条的执行计划。
例如在表里面有多个索引的时候,决定使用哪一个索引;或者在一个语句有多表关联(join)的时候,决定各个表的链接顺序。好比你执行下面这样的语句,这个语句是执行两个表的join:
mysql> select * from t1 join t2 using(ID) where t1.c=10 and t2.d=20;
这两种执行方法的逻辑结果是同样的,可是执行的效率会有不一样,而优化器的做用就是决定选择使用哪个方案。
优化器阶段完成后,这个语句的执行方案就肯定下来了,而后进入执行器阶段。若是你还有一些疑问,好比优化器是怎么选择索引的,有没有可能选择错等等,不要紧,我会在后面的文章中单独展开说明优化器的内容。
MySQL经过解析器知道了你要作什么,经过优化器知道了该怎么作,因而就进入了执行器阶段,执行器会根据一系列的执行计划去调用存储引擎的接口去完成SQL的执行。
开始执行的时候,要先判断一下你对这个表T有没有执行查询的权限,若是没有,就会返回没有权限的错误,以下所示(在工程实现上,若是命中查询缓存,会在查询缓存放回结果的时候,作权限验证。查询也会在优化器以前调用precheck验证权限)。
mysql> select * from T where ID=10; ERROR 1142 (42000): SELECT command denied to user 'b'@'localhost' for table 'T'
若是有权限,就打开表继续执行。打开表的时候,执行器就会根据表的引擎定义,去使用这个引擎提供的接口。
好比咱们这个例子中的表T中,ID字段没有索引,那么执行器的执行流程是这样的:
至此,这个语句就执行完成了。
对于有索引的表,执行的逻辑也差很少。第一次调用的是“取知足条件的第一行”这个接口,以后循环取“知足条件的下一行”这个接口,这些接口都是引擎中已经定义好的。
参考:
【1】:《高性能MySQL》
【2】:极客时间 《MySQL实战45讲》
【3】:《MySQL技术内幕 InnoDB存储引擎》