课程来自极客时间《MySQL实战45讲》
文章目录
MySQL可分为Server层和存储引擎层两部分

一、Server层
Server层包括连接器、查询缓存、分析器、优化器、执行器等,涵盖MySQL的大多数核心服务功能,以及所有的内置函数(如日期、时间、数学和加密函数等),所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图等。
1、连接器
连接器负责跟客户端建立连接、获得权限、维持和管理连接
mysql -h$ip -P$port -u$user -p
用户名密码通过验证后,连接器会到权限表里查出你拥有的权限。之后此连接里面的权限判断逻辑,都会依赖此时读到的权限(就算更改权限,也得断开重连就是这个原因)
连接完成后,可以使用以下命令查看系统连接
show processlist
- 长连接:客户端持续有请求,则一直使用同一个连接
- 短连接:每次执行完很少的几次查询就断开连接,下次查询再重新建立一个
1.1、全部使用长连接的弊端?
由于MySQL在执行过程中临时使用的内存是管理在连接对象里面,这些资源会在连接断开的时候才释放,如果累积长连接,可能导致内存占用太大,被系统强行杀掉(OOM)
1.2、解决方案
- 定期断开长连接
- 在MySQL5.7及5.7之后,通过执行mysql_reset_connection来重新初始化连接资源。这个过程不需要重连和重新做权限验证,但是会将连接恢复到刚刚创建完时的状态。
2、查询缓存
MySQL拿到一个查询请求后,会先到查询缓存看看,之前是不是执行过这条语句。
之前执行过的语句及其结果可能会以key-value对的形式,被直接缓存在内存中。key是查询的语句,value是查询的结果。
- 如果你的查询能够直接在这个缓存中找到key,那么这个value就会被直接返回给客户端。
- 如果语句不在查询缓存中,就会继续后面的执行阶段。执行完成后,执行结果会被存入查询缓存中。
2.1、为什么大多数情况下不要使用查询缓存?
查询缓存的失效非常频繁,只要有对一个表的更新,这个表上所有的查询缓存都会被清空。对于更新压力大的数据库来说,查询缓存的命中率会非常低。
2.2、如何指定查询缓存?
不使用查询缓存:将参数query_cache_type
设置成DEMAND
使用查询缓存:用SQL_CACHE显式指定,如下:
mysql> select SQL_CACHE * from T where ID=10;
MySQL8.0将查询缓存整块删掉了!
3、分析器
作用:知道你要做什么
前提:没有命中查询缓存
-
分析器先会做“词法分析”
- 你输入的是由多个字符串和空格组成的一条SQL语句,MySQL需要识别出里面的字符串分别是什么,代表什么。
-
其次,会做“语法分析”
- 根据词法分析的结果,语法分析器会根据语法规则,判断你输入的这个SQL语句是否满足MySQL语法。
4、优化器
优化器是在表里面有多个索引的时候,决定使用哪个索引;
或者在一个语句有多表关联(join)的时候,决定各个表的连接顺序。
比如执行下面这样的语句,这个语句是执行两个表的join:
mysql> select * from t1 join t2 using(ID) where t1.c=10 and t2.d=20;
- 既可以先从表t1里面取出c=10的记录的ID值,再根据ID值关联到表t2,再判断t2里面d的值是否等于20。
- 也可以先从表t2里面取出d=20的记录的ID值,再根据ID值关联到t1,再判断t1里面c的值是否等于10。
两种执行方法的逻辑结果是一样的,但是执行的效率会有不同,而优化器的作用就是决定选择使用哪一个方案。
5、执行器
作用:执行语句
- 判断有无权限
- 打开表继续执行
二、存储引擎层
存储引擎层负责数据的存储和提取。其架构模式是插件式的,支持InnoDB、MyISAM、Memory等多个存储引擎。现在最常用的存储引擎是InnoDB,它从MySQL 5.5.5版本开始成为了默认存储引擎。可以在创建表时使用engine=“存储引擎”来指定你需要的存储引擎来创建表。
三、问题
如果表T中没有字段k,而你执行了这个语句 select * from T where k=1, 那肯定是会报“不存在这个列”的错误: “Unknown column ‘k’ in ‘where clause’”。你觉得这个错误是在哪个阶段报出来的呢?
答案:分析器,在分析器进行分析时,会查看表字段是否存在。