一、一条SQL的执行流程

二、SQL执行流程
1、连接
客户端要通过3306端口与MySQL服务端建立连接,MySQL有专门处理连接的模块,连接的时候需要验证权限。
查看MySQL当前有多少个连接:
show global status like 'Thread%';

客户端每产生一个连接或会话,服务端就创建一个线程来处理。反之若要杀死会话,就kill掉对应线程。MySQL会把长时间不活动的(SLEEP)连接自动断开。
查看会话超时时间:
show global variables like 'wait timeout';--非交互式超时时间,如JDBC程序
show global variables like 'interactive timeout';--交互式超时时间,如数据库工具
--默认都是28800秒,8小时
查看最大连接数:
show variables like 'max connections';--在5.7版本中默认是151个,最大可以设置成100000
2、缓存
MySQL内部自带了一个缓存模块但默认是关闭的。在8.0版本中,查询缓存已被移除。
因为MySQL的缓存要求SQL必须一摸一样,语句中不同的空格、大小写都被认为是不同的SQL;若表中任意一条数据发生了变化,这张表相关的所有缓存都会失效。对于有大量数据更新的应用,非常不适合。
查看mysql缓存是否启用:
show variables like 'query_cache%';
3、解析器
- **词法解析:**将一个SQL语句分解成一个个单词
- **语法解析:**对SQL语句进行语法检查,通过后根据MySQL定义的语法规则,基于SQL语句生成一个数据结构-解析树(select lex)。

4、预处理器(Preprocessor)
检査生成的解析树,解决解析器无法解析的语义。检査表和列名是否存在,检査名字和别名,保证没有歧义。
预处理后会得到一个新的解析树。
5、查询优化器(Query Optimizer)
根据解析树生成不同的执行计划(Execution Plan),选择一种最优的执行计划。MySQL使用基于开销(cost)的优化器,选择开销最小的执行计划。
査看査询SQL的开销:
show status like 'Last_query_cost';
优化器并不是万能的,它最终会把解析树变成一个可査询的执行计划,在SQL语句前面加上EXPLAIN,就可以看到执行计划的信息:
EXPLAIN select name from user where id=1;
如果要得到更详细的信息,可以用FORMAT=JSON,或者开启optimizer trace。
EXPLAIN FORMAT=JSON select name from user where id=1;
6、执行引擎(Execution Engine)
最优执行计划确定后,执行引擎负责执行对应的执行计划,通过调用存储引擎提供的API完成操作,并返回结果。
7、存储引擎
数据真正存放的地方。MySQL支持不同类型的存储引擎。再往下就是内存或者磁盘。
三、MySQL的存储引擎
1、InnoDB
MySQL 5.7中的默认存储引擎
- 支持事务,支持外键,数据的完整性、一致性更高。
- 支持行级锁、表级锁。
- 支持读写并发,写不阻塞读(MVCC)。
- 聚簇索引,可以减少I/O,提升査询效率。
2、MyISAM
表级锁限制了读/写的性能,通常用于只读或以读为主的工作。
- 支持表级锁(插入和更新会锁表)。
- 不支持事务。
- 拥有较高的插入(insert)和查询(select)速度。
- 存储了表的行数(count速度更快)。
3、Memory
将所有数据存储在RAM中。
- 读写的速度很快。
- 数据库重启或者崩溃,数据会全部消失。
- 只适合做临时表。
4、CSV
实际上是带有逗号分隔值的文本文件。允许以CSV格式导入或转储数据。在正常操作期间将数据保存在innodb表中,只在导入或导出阶段使用CSV表。
- 不允许空行,不支持索引。
- 格式通用,可以直接编辑,适合在不同数据库之间导入导出。
5、Archive
紧凑的未索引的表,用于存储和检索大量很少引用的历史、存档或安全审计信息。
- 不支持索引。
- 不支持update delete。
6、如何选择
- 对数据一致性要求比较高,需要事务支持,选择InnoDB。
- 数据读多写少,对查询性能要求比较高,选择MyISAM。
- 需要用于查询的临时表,选择Memory。
- 需要存储归档数据,选择Archive。
四、MySQL分层架构
