1. MySQL 架构

MySQL 由两部分组成:

  1. 提供服务的 Server 部分,它除了提供核心服务,还提供函数库、跨存储引擎的功能(存储过程、触发器、视图等)
  2. 存储数据的引擎部分:默认为 InnoDB 引擎(MySQL 5.5.5 后)。引擎层使用的是插件框架,除了 InnoDB,你还可以使用 MyISAM、Memory 等引擎。Server 层通过存储引擎提供的接口来访问引擎

Server部分执行一条 MySQL 语句的流程如下:

  1. 连接 MySQL Server,由连接器进行权限检查。并从权限表中查询连接具备的所有权限,供后续执行器使用;当你在连接过程中修改权限,并不会立即生效,新权限在重连后生效。

    • 长连接的问题:每个连接会分配一个内存池(存执行过程中临时使用的内存),如果连接长时间不关闭,内存会一致增长,如果超出系统内存,操作系统会因为 OOM 而杀掉进程,从外部看上去就像 MySQL 重启了一样。建议使用长连接,而解决长连接的方式是 ① 定期的重连 ② 在 MySQL 5.7 及之后,使用 mysql_reset_connection 重新初始化连接。

    • 短连接的问题:连接过程是复杂的,频繁的短连接会消耗资源。

    • 不考虑网络问题,连接器的 Keepalive 时间为 8 小时,wait_timeout 参数控制。

  2. 通过权限检查后,会进入查询缓存,如果缓存中有该语句(key),则直接返回缓存中数据(value),否则进入后续步骤

    一般不建议使用查询缓存,因为一旦有更新发生,查询缓存就会清空,除非你的数据是静态的、非更新数据

    禁用查询缓存的方法:参数 query_cache_type 设置为 DEMAND

  3. 进入分析器:根据词法分析,识别出语句中的各个词的含义;根据语法分析,分析这条语句的语法是否合法

  4. 进入优化器:在一个表有多个索引的情况下,优化器会分析该语句是否使用索引,以及使用哪个索引;对于 join 语句,优化器会根据执行效率,选择先查询哪个表,再到另一个表中匹配,还是相反。

  5. 进入执行器:首先判断连接是否具有执行权限。执行器会根据优化结果,调用引擎的接口进行查询,例如全表扫描的步骤如下

    1. 调用查询表第一行的接口,判断返回值是否符合条件,符合就将结果插入结果集
    2. 调用查询表的下一行的接口,判断是否符合查询条件
    3. 判断是否是结尾,否则循环第 2 步
    4. 将结果集返回给客户端

    在索引上查询的步骤也差不多,只不过是把调用第一行/下一行的接口换为调用第一个/下一个符合条件的接口。

    执行器会把每次调用接口后扫描的行数累加,以 rows_examined 值存储在慢查询语句中。

本文是学习《MySQL实战45讲》的笔记