前言
平时我们使用数据库查询,我们看到的只是输入一条语句,返回一个结果,却不太关心这条语句在MySQL内部的执行过程,所以今天我想把MySQL的查询过程拆解一下,借由这个过程,对MySQL有更深入的了解,大体来说,MySQL可以分为Server层和存储引擎层两部分,Server层包包括连接器、查询缓存、分析器、优化器、执行器等。存储引擎层负责数据的存储和提取。示例图如下:
连接器
第一步需要先连接到这个数据库上,负责处理连接的就是连接器,连接器负责跟客户端简历连接、获取权限、维持和管理连接。
查询缓存
连接建立完成后,那就可以执行select语句了,首先查询缓存,之前是不是执行过这条语句,之前执行过得语句及其结果可能会以key-value的形式缓存在内存中,key是查询的语句,value是查询的结果。如果命中缓存,那么对应的value就会直接返回给客户端。否则继续后面的执行阶段,执行完成后,执行结果会被存入查询缓存中。我们可以看到,如果命中缓存,可以直接返回结果,效率会很高。
缓存是一把双刃剑,有利也有弊,对于更新比较频繁的数据库来说,数据每次更新,这个表上所有的查询缓存都会被清空,这样对数据库就会造成一定压力,所以查询缓存我们应该按需使用。
分析器
如果没有命中查询缓存,则继续执行后续过程,首先需要对SQL语句进行解析,分析器先会做“词法分析”,识别出里面的字符串分别代表什么,然后就要做“语法分析”,根据词法分析的结果,语法分析器会根据语法规则,判断你输入的这个SQL语句是否满足MySQL语法。
优化器
经过了分析器,MySQL就知道你要做什么了,在执行前还要经过优化器的处理。
优化器是在表里面有多个索引的时候,决定使用哪个索引,或者在一个多表关联的语句中,决定各个表的连接书序。
优化器执行完成后就生成一个执行方案,然后进入执行器阶段。
执行器
开始执行的时候,先要判断一下你对这个表有没有执行查询的权限,如果没有,则会返回没有权限的错误,如果有权限,就打开表根据上一步生成的执行计划继续执行,并将所有满足条件的行组成记录集作为结果集返回给客户端。
小结
对于一个SQL语句完整执行流程如下:连接,权限校验(如果命中缓存)---》查询缓存---》分析器---》优化器---》权限校验---》执行器---》引擎。