Sql 语句执行过程详解
综述
- 服务器接收到从客户端发来的SQL语句
- 数据库高速缓存查询,命中缓存直接返回存储的结果。否则进入下一阶段
- SQL解析、预处理,优化器生成执行计划
- MySQL根据执行计划,调用存储引擎API执行查询
- 返回结果给客户端
要点
查询缓存
MySQL保存查询返回的完整结构。命中缓存跳过了解析、预处理、优化、执行阶段。
查询缓存系统会跟踪查询中涉及的任何表,如果有变化,则和此表相关的缓存数据失效。
MySQL将缓存存放在一个引用表中,通过哈希值引用,哈希值包括以下因素:查询运语句本身、要查询的数据库、客户端协议的版本等一些其他影响返回结果的信息。
判断缓存命中时,不会进行语句解析,直接使用原始SQL语句和客户端发来的其他信息,任何字符的不同,如空格、注解等都会导致缓存不命中。
当查询语句中有一些不确定数据时,查询结果不会被缓存。例如包含函数NOW()或CURRENT_DATE()的查询。包含任意用户自定义函数,存储过程,用户变量,临时表,mysql数据库的系统表或者包含任一列级别权限的表,都不会被缓存。
解析和预处理
语法检查,解析器通过关键字将SQL语句解析,生成解析树。解析器将使用MySQL语法规则验证和解析查询。
语义检查,预处理器根据一些MySQL规则进行进一步检查解析树是否合法,例如检查数据表和列是否存在,名字和别名是否有歧义。
查询优化器
查询优化器将解析树转换为执行计划。一条语句可以有多种执行计划。优化器选择其中最优计划执行。
生成执行计划过程耗时较多,特别是存在许多可选执行计划时。
执行计划可以缓存,当相似语句再次输入时,可以使用缓存的执行计划,跳过生成过程,提高执行SQL速度。
执行计划缓存
MySQL使用基于成本的查询优化器(Cost-Based Optimizer,CBO)。它尝试预测一个查询使用某种执行计划时的成本,并选择其中成本最少的一个。
优化器会根据优化规则对关系表达式进行转换,意思是一个关系表达式经过优化规则后生成另一个关系表达式,同时原有表达式也保留。经过一系列转换生成过个执行计划,后CBO统计信息和代价模型(Cost Model)计算每个执行计划的Cost,挑选最小Cost执行计划。由上可知,CBO中有两个依赖:统计信息和代价模型。统计信息的准确与否、代价模型的合理与否都会影响CBO选择最优计划。
优化器原理时分复杂,这里不详细讲解。。
查询执行引擎
解析和优化之后生成最优执行计划,MySQL的查询引擎根据这个执行计划来完成查询。这里查询计划是一个数据结构,而不是和其他关系型数据库那样生成对应的字节码。
返回结果给客户端
如果可以缓存,在此阶段会将结果缓存在查询缓存中。
MySQL将结果集返回给客户端是一个增量、逐步返回的过程。在查询生成第一条结果时,MSQL就可以开始向客户端逐步返回结果集了。
参考文章:
https://yq.aliyun.com/articles/633731