昔日庖丁解牛,未见全牛,所赖者是其对牛内部骨架结构的了解,对于MySQL亦是如此,只有更加全面地了解SQL语句执行的每一个过程,才能更好的进行SQL的设计和优化。 当但愿MySQL可以以更高的性能运行查询时,最好的办法就是弄清楚MySQL是如何优化和执行查询的。一旦理解了这一点,不少查询优化工做实际上就是遵循一些原则可以按照预想的合理的方式运行。 以下图所示,当向MySQL发送一个请求的时候,MySQL到底作了什么:mysql
MySQL查询缓存保存查询返回的完整结构。当查询命中该缓存时,MySQL会马上返回结果,跳过了解析、优化和执行阶段。 查询缓存系统会跟踪查询中涉及的每一个表,若是这些表发生了变化,那么和这个表相关的全部缓存数据都将失效。 MySQL将缓存存放在一个引用表中,经过一个哈希值引用,这个哈希值包括了如下因素,即查询自己、当前要查询的数据库、客户端协议的版本等一些其余可能影响返回结果的信息。 当判断缓存是否命中时,MySQL不会进行解析查询语句,而是直接使用SQL语句和客户端发送过来的其余原始信息。因此,任何字符上的不一样,例如空格、注解等都会致使缓存的不命中。 当查询语句中有一些不肯定的数据时,则不会被缓存。例如包含函数NOW()或者CURRENT_DATE()的查询不会缓存。包含任何用户自定义函数,存储函数,用户变量,临时表,mysql数据库中的系统表或者包含任何列级别权限的表,都不会被缓存。 有一点须要注意,MySQL并非会由于查询中包含一个不肯定的函数而不检查查询缓存,由于检查查询缓存以前,MySQL不会解析查询语句,因此也没法知道语句中是否有不肯定的函数。 事实则是,若是查询语句中包含任何的不肯定的函数,那么其查询结果不会被缓存,由于查询缓存中也没法找到对应的缓存结果。 有关查询缓存的配置以下所示。sql
对查询缓存的优化是数据库性能优化的重要一环。判断流程大体以下图所示。数据库
缓存命中率能够经过以下公式计算:Qcache_hits/(Qcache_hits + Com_select)来计算。缓存
解析器经过关键字将SQL语句进行解析,并生成对应的解析树。MySQL解析器将使用MySQL语法规则验证和解析查询。 预处理器则根据一些MySQL规则进行进一步检查解析书是否合法,例如检查数据表和数据列是否存在,还会解析名字和别名,看看它们是否有歧义。性能优化
查询优化器会将解析树转化成执行计划。一条查询能够有多种执行方法,最后都是返回相同结果。优化器的做用就是找到这其中最好的执行计划。 生成执行计划的过程会消耗较多的时间,特别是存在许多可选的执行计划时。若是在一条SQL语句执行的过程当中将该语句对应的最终执行计划进行缓存,当类似的语句再次被输入服务器时,就能够直接使用已缓存的执行计划,从而跳过SQL语句生成执行计划的整个过程,进而能够提升语句的执行速度。服务器
MySQL使用基于成本的查询优化器(Cost-Based Optimizer,CBO)。它会尝试预测一个查询使用某种执行计划时的成本,并选择其中成本最少的一个。 优化器会根据优化规则对关系表达式进行转换,这里的转换是说一个关系表达式通过优化规则后会生成另一个关系表达式,同时原有表达式也会保留,通过一系列转换后会生成多个执行计划,而后CBO会根据统计信息和代价模型(Cost Model)计算每一个执行计划的Cost,从中挑选Cost最小的执行计划。由上可知,CBO中有两个依赖:统计信息和代价模型。统计信息的准确与否、代价模型的合理与否都会影响CBO选择最优计划。 有关优化器的原理十分复杂,这里就不进行详细讲解了,你们能够自行学习。微信
在解析和优化阶段,MySQL将生成查询对应的执行计划,MySQL的查询执行引擎根据这个执行计划来完成整个查询。这里执行计划是一个数据结构,而不是和其余的关系型数据库那样生成对应的字节码。数据结构
若是查询能够被缓存,那么MySQL在这个阶段页会将结果存放到查询缓存中。 MySQL将结果集返回给客户端是一个增量、逐步返回的过程。在查询生成第一条结果时,MySQL就能够开始向客户端逐步返回结果集了。函数
订阅最新文章,欢迎关注个人微信公众号性能