MySQL 语句执行过程
在 MySQL 执行语句中,需要经过一系列模块的协同工作,最终完成 SQL 语句的执行。
下图展示了 SQL 语句执行的过程。
其执行过程可以整体描述为:
- 客户端与连接器建立连接,并发送用户名密码等信息进行认证。连接器将在认证完成后拉取用户的权限信息并缓存,并在随后的整个会话中使用这些权限信息进行鉴权。因此在建立连接后变更的权限信息在重新建立连接之前不会生效。
- 在 MySQL 5.7 中,SQL 查询语句执行前会把整个 SQL 语句字符串作为 key 检查在查询缓存中存在。当发现缓存存在时就可以直接从查询缓存中返回结果。当表中的数据发生变更时,与这张表相关的所有查询缓存都会失效,因此在数据变化较多时,缓存的命中率不高。同时, SQL 语句中的任何微小变化,包括注释等无关元素都会导致缓存不命中。在这些不利条件下,MySQL 8.0 取消了这一模块。
- 在查询缓存模块后,MySQL 需要对 SQL 语句进行解析,生成语法树以便后续的执行流程使用。这一过程中,需要经过词法分析、语法分析的步骤。词法分析对 SQL 语句按词法规则解析为关键字等词元;语法分析则检查检查这些词元是否符合 SQL 的语法规则。
- 预处理器基于解析器生成的语法树,进行简单的处理。包括:检查使用的表、字短是否存在,将 SELECT 语句中的 * 展开为全字段等。
- 优化器则会分析语句的执行成本,包括索引的使用方式等,生成一个优化的执行计划。
- 执行器则会根据执行计划与执行引擎进行交互,并对执行引擎返回的数据进行检查,将符合条件的数据返回客户端。这一返回的过程是持续的,每读取到一条符合的数据便直接返回,并在所有符合条件的数据完成后发送完成信号。
- 与执行器交互的执行引擎负责数据的存取工作。基于这一抽象,MySQL 中的存储引擎可以根据需求进行切换。数据的索引便由这一模块进行维护和使用。
这一完整过程中,可以将 MySQL 划分为 Server 层和执行引擎层两层。SQL 中的函数等功能都由 Server 层实现,记录 SQL 执行记录的 binlog 也由 Server 层实现。而执行引擎层则维护了底层的数据结构,包括索引、锁的机制都由执行引擎提供。