mySQL查询执行的过程
01
查询的流程图
当我们希望MySQL能够以更高的性能进行查询时,弄清楚MySQL中是如何优化和执行查询的就显得很有必要,这里,先搬出来一张图镇楼:
这张图写清楚了一个查询在MySQL中的执行过程:
1、客户端发送一条查询给服务器。
2、服务器先检查查询缓存,如果命中了缓存,则会进行权限校验,权限校验通过,直接返回结果。
3、如果没有命中缓存,则进行SQL解析、预处理、再由优化器进行查询优化,计算各项查询方法的成本、生成对应的执行计划。
4、MySQL根据执行计划,调用存储引擎的API来执行查询。
5、将结果返回给客户端。
这里需要注意一点,客户端和服务器交互的时候是使用的MySQL的通信协议,关于通信协议,最重要的参数是max_allowed_packet,这个参数决定了服务端单个包最大接受的数据量。
02
查询状态分析
当服务器开始返回结果时,最好的方法是等待结果返回,如果中间使用ctrl+c的命令强行终止输出,这种方法是无法停止服务器的结果输出的,反而容易造成一定的问题。在我们查询的过程中,MySQL会维护一个查询状态,也就是我们使用show processlist来进行查看的时候的一些状态值,例如:
sleep,说明线程正在等待客户端发送新的请求
query,线程正在执行查询或者正在将结果发送给客户端
locked,该线程正在等待表锁
analyzing and statistics,线程正在收集存储引擎的统计信息,并将生成查询的执行计划
copying to tmp table,线程正在执行查询,并且将结果集都复制到一个临时表中,这种状态一般不会出现,除非在group by或者文件排序、union等操作的时候才会出现
sorting result,线程正在对查询的结果集进行排序。
sending data,这个状态表示服务器可能在多个状态之间传送数据或者在生成结果集想客户端返回
03
查询缓存
在解析查询的SQL的时候,如果这个查询时打开的,那么MySQL会优先在缓存中查询该SQL是否命中,这个过程是一个大小写敏感的过程,即使只有一个字节不同,也不会命中缓存,如果恰好命中了缓存,则下一步不是返回结果,而是查看权限是否有问题,如果检测权限有问题,则不会返回结果,如果权限没有问题,则会返回结果给客户端。这一点很重要,需要保持谨慎。
04
查询的优化处理
查询优化处理包含多个部分,例如解析SQL、预处理、优化SQL执行计划等等,其中:
语法解析器是专门的解析MySQL语法的,一旦发现错误的关键字、数据类型、关键字顺序、字段和数值顺序等等,一旦发现错误,则立即停止查询。
预处理器则是语法解析器的一个补充,它会检查数据列和数据表是否存在,解析别名是否有歧义等等
查询优化器主要是讲SQL转化为执行计划,一条SQL有多种执行方式,查询优化器就是为了找到代价最低的那一条方式,生成执行计划,它的工作包括但不限于子查询优化、提前终止查询、预估数据并转化为常数表达式、冲新定义关联表的顺序、使用等价变换规则等等。查询优化器是一个非常复杂的部件,已经相当的智能了,但是有时候还是很难给出最优的结果,如果你希望用你自己的理解来生成执行计划,其实可以使用强制索引的方法来调整查询优化器的执行计划,单这个操作并不是每次都能如愿。