一、逻辑架构分析
MySQL大致分为四层:连接层、服务层、引擎层、存储层。大致如下:
1.连接层
客户端访问 MySQL 服务器前,做的第一件事就是建立 TCP 连接。
连接层对应图中的Connection Pool。是MySQL服务器提供给外部客户端的一个连接接口,客户端可以通过不同的方式进行连接,如JDBC、ODBC和原生方式API等(其本质还是建立TCP连接)。
连接层不仅是建立连接,还需要进行认证授权、维持连接等操作。
- 为了解决TCP无限创建与频繁创建销毁带来的资源耗尽和性能下降问题。mysql服务器有专门的TCP连接池限制链接数,采用长连接方式来复用TCP连接。
- TCP 连接收到请求后,必须要分配给一个线程专门与这个客户端的交互。所以还会有个线程池,去走后面的流程。每一个连接从线程池中获取线程,省去了创建和销毁线程的开销。
2.服务层
服务层有多个模块:
- SQL interface:SQL接口
用于接收用户的SQL命令,并且返回用户需要查询的结果。比如SELECT ... FROM就是调用SQL Interface
- Parser:解析器
对SQL 语句进行语法分析、语义分析。将SQL语句分解成数据结构(语法树),并将这个结构传递到后续步骤,以后SQL语句的传递和处理就是基于这个结构的。如果在分解构成中遇到错误,那么就说明这个SQL语句是不合理的。
- Optimizer: 查询优化器
使用查询优化器确定SQL语句的执行路径,生成一个执行计划。这个执行计划表明应该使用哪些索引进行查询(全表检索还是使用索引检索),表之间的连接顺序如何,最后会按照执行计划中的步骤调用存储引擎提供的方法来真正的执行查询。
- Caches & Buffers: 查询缓存组件
查询的缓存模块。该模块在8.0之后被移除,因为其极地的命中率。
3.引擎层
插件式存储引擎层( Storage Engines),真正的负责了MySQL中数据的存储和提取,对物理服务器级别维护的底层数据执行操作,服务器通过API与存储引擎进行通信。不同的存储引擎具有的功能不同,这样 我们可以根据自己的实际需要进行选取。
show engines;命令查看支持的存储引擎。
4.存储层
所有的数据,数据库、表的定义,表的每一行的内容,索引,都是存在文件系统上,以文件的方式存在的,并完成与存储引擎的交互。
数据存放路径由datadir指定。默认是/var/lib/mysql下。
二、SQL的执行流程
SQL查询流程大致为:
1.查询缓存(8.0无这一步),如果有缓存直接返回
2.解析器:在解析器中对 SQL 语句进行语法分析、语义分析。词法分析:识别出sql语句中的关键字和一些表名称、别名等。语法分析:根据语法规则,判断你输入的这个SQL 语句是否满足 MySQL 语法。
如果SQL语句正确,则会生成一个这样的语法树:
3. 优化器:在优化器中会确定SQL 语句的执行路径,比如是根据全表检索,还是根据索引检索等。
经过了解析器,MySQL就知道你要做什么了。在开始执行之前,还要先经过优化器的处理。一条查询可以有很多种执行方式,最后都返回相同的结果。优化器的作用就是找到这其中最好的执行计划。
4.执行器:真正的去执行SQL,在执行之前需要判断该用户是否具备权限 。如果没有,就会返回权限错误。如果具备权限,就会调用存储引擎的API,具体执行还是看执行引擎的实现。
三、查看执行流程
1. 确认profiling 是否开启
select @@profiling;
show variables like 'profiling%';
我们需要把 profiling 打开:
set profiling=1;
2.查询sql
随便执行一个 SQL 查询
3. 查看profiles
查看当前会话所产生的所有 profiles:
show profiles; # 显示最近的几次查询
图中的Query_ID表示该条查询的id号,Duration表示执行该语句所花费的所有时间总和,Query表示查询语句。
4. 查看profile
具体的查询某一个profile:
show profile; #查询最近一条profile的详细信息
show profile for query 2; #根据query的id号查询为2的profile
show profile cpu,block io for query 1; #详细查询
结果如下图: