客户端将查询发送到服务器
服务器检查查询缓存,如果找到了,就从缓存中返回结果,否则进行下一步
服务器解析,预处理和优化查询,生成执行计划
查询执行引擎调用存储引擎API执行查询
将服务器结果发送回客户端
如图:
尽管不需要理解mysql客户端服务器协议的内部细节,但是还是需要了解其大致轮廓,这个协议是半双工的。这意味着mysql服务器在某个给定的时间,可以发送或者接收数据,但是不能同时接收和发送。这也意味着没有办法截断消息
这种协议让mysql的沟通简单又快捷,但是有限制,其中一个就是无法进行流程控制,一旦一方发送消息,另一方在发送回复之前必须提取完整的消息。
客户端用一个数据包将查询发送到服务器,这就是为什么max_packet_size这个配置参数对于大查询很重要的原因,一旦客户端发送了查询,唯一能做的就是等待j结果。
查看状态
每个mysql连接,或者叫线程,在任意一个给定的时间都有一个状态来标示正在进行的事情,有几种方法可以查看状态,但是最容易地市使用show full processlist命令,当一个查询处于其生命周期中的时候,它的状态会改变很多次,一共有12中状态,列出几种并解释其含义
休眠:线程在等待客户端的新查询
查询:线程正在执行查询或者往客户端发送数据
锁定:线程在等待服务器授予一个表锁,由存储引擎执行的锁,比如innodb的行锁,不会让进程进入locked状态。
分析和统计:线程在查询存储引擎的统计信息并并且优化查询
拷贝到磁盘上的临时表:线程在处理查询并且把结果拷贝到暂存表,其结果也许是group by,对文件排序,使用uinon,如果状态后面有on disk,那么说明mysql正在把内存中的表拷贝到磁盘上的表里面
排序结果:线程在对结果进行排序
发送数据:这有几种含义,线程也许是在查询的各个状态之间传递数据,也可能是在产生结果,还可能是把结果返回给客户端。
在解析一个查询之前,如果开启了缓存,mysql会检查查询缓存,进行大小写敏感的哈希查找,即使查询和缓存中的查询只有一个字节的差异,也表示不匹配,查询就会进入到下一个状态。
如果在mysql的缓存中发现了一个匹配,那么在返回缓存之前,必须检查查询的权限,因为mysql在缓存中存库了表的信息,所以这时可能根本不用 解析查询,如果权限没有问题,那么mysql就从缓存中提取数据,然后返回给客户端,这样就绕过了查询执行的所有步骤,不需要对查询进行解析,优化和执行
查询优化过程
查询省名周期的下一步是把查询转变成执行计划,它有几个子过程,解析,预处理,和优化。错误在这个过程中的任何一部都可能出现。