从整体架构来说,MySQL 可以分为服务层和存储引擎层:

  • 服务层:管理连接、缓存、SQL 验证优化、SQL 执行等
  • 存储引擎层:负责数据处理,向上提供接口

服务层包含:连接器、缓存、分析器、优化器、执行器、存储过程、触发器、视图和内置函数

连接器主要负责管理客户端的连接、权限验证等。我们可以通过 show processlist 查看当前连接的状态。用户的权限只在连接建立时获取,后续管理员修改不会影响当前已连接用户的权限。

连接默认保持 8 小时,超时自动断开。这样做的好处在于,短时间内客户端一直使用同一连接,避免多次建立连接的资源消耗。缺点在于连接长期占用内存,可能导致内存溢出,最终被系统杀死,一般需要定期断开长连接、或执行大查询后断开连接。

缓存主要提高查询效率,当缓存命中时直接从缓存中返回。一般优化效果不大,因为缓存涉及到的表一旦被修改,缓存就会被删除,只适合存放部分静态数据

分析器主要负责检查 SQL,检查表名、列名是否存在,判断 SQL 是否符合 MySQL 语法规范

优化器主要负责优化 SQL,确定索引的使用,join 表的连接顺序

执行器主要负责调用存储引擎接口,进行数据的读取,在执行具体语句前,先进行权限的检查。执行前才检查权限是因为:如使用触发等情况,只有在执行器阶段才能确定权限,优化器阶段无法验证

如果设置了慢查询,可以在日志中通过 rows_examined 找到扫描的行数。

慢查询:所谓慢查询就是指查询语句的执行时间超过了 long_query_time 参数设定的时间阈值,慢查询日志会记录这部分 SQL

存储过程主要为了封装和复用 SQL 语句,提高性能、但编写困难,一般用户没有创建存储过程的权限。

触发器本质是与表有关的对象,在满足定义时执行触发器中定义的 SQL 语句集合。其中触发器效率很差,一般不建议使用。

视图是一个虚拟表,显示 sql 查询结果。使用视图可以对不同用户分权限展示不同列、联合多表查询结果等

内置函数顾名思义就是一组函数,如 abs()、max()、sum() 等等

存储引擎负责数据的具体存储,常见的存储引擎有 InnoDB、MyISAM 等。不同的存储引擎实现大不相同,此时根据具体需求选择合适的存储引擎


下面我简单概述一次 select 语句执行全过程:

  1. 客户端发起连接,连接器创建连接,验证客户端权限
  2. 客户端发送 SQL,服务端接收
  3. 分析器分析 SQL 是否正常,表、列是否存在,如果都正常向下继续执行
  4. 在缓存中查找,如果命中从缓存中返回,否则继续向下走
  5. 判断索引使用,优化 SQL ,调整判断顺序等
  6. 调用存储引擎接口查询数据,结果返回

上面忽略了存储引擎中可能存在的加解锁、挂起等操作,大家知道就好。我们可以通过 profiling 查看 SQL 执行过程,常用 SQL 如下:

// 查看执行过程是否打开,0表示没打开,1表示打开
select @@profiling;
// 打开执行过程
set profiling = 1;
// 查看所有被记录到的执行过程
show profiling;
// 查看 Query_ID 为 x 的 sql 执行过程,Query_ID 的值可以通过上一条指令看到
show profile for query x;

除了上面提到的这些模块,MySQL 还包含日志模块,Server 层包含 binlog 日志,存储引擎层不同的存储引擎对应不同的日志,所起到的作用也大不相同,关于 MySQL 日志后面笔者单独整理。