常言道,看待一个事情要先知全貌,从高维度认识、理解,然后再深入各个细节,一一击破。MySQL的学习也不例外,那么你知道一条SQL在MySQL中执行要经历哪些步骤吗?每个步骤都有MySQL的哪些“零件”参与吗?如果不清楚的话,可以阅读本文。
在MySQL客户端或者JAVA应用程序中查询一条最简单的语句比如select * from T where ID =10;
你知道经历哪些步骤吗?
你要执行查询语句前肯定要先和MySQL建立连接啊,那怎么建立连接呢?
可以通过下面的命令:
mysql -h ip -P port -u$user -p
复制代码
Access denied for user
错误,客户端程序结束执行这个用于连接的“零件”就是MySQL的连接器,它主要负责跟客户端建立连接、获取权限、维持和管理连接。
现在连接建立好了,相当于客户端和MySQL服务端的“传输管道”有了,开始查数据了。
都说性能不够,缓存来凑,MySQL“为了性能”,也实现了查询缓存。
所以关键点在于MySQL表的更新频率以及缓存的命中率,我们可以根据下面命令查看监控查询缓存:
show status like '%Qcache%';
复制代码
Qcache_hits:
表示有 多少次命中缓存
。我们主要可以通过该值来验证我们的查询缓存的效果。数字越大,缓存效果越理想。Qcache_inserts:
表示多少次未命中然后插入
,意思是新来的SQL请求在缓存中未找到,不得不执行查询处理,执行查询处理后把结果insert到查询缓存中。这样的情况的次数越多,表示查询缓存应用到的比较少,效果也就不理想。当然系统刚启动后,查询缓存是空的,这也正常。这上面一个过程就是MySQL的查询缓存操作。
但是实际情况是查询缓存往往弊大于利,因为查询缓存的失效非常频繁,一般建议大家在静态表里使用查询缓存。但是在MySQL 8.0中已经去掉了查询缓存。
如果没有命中查询缓存,就要开始真正去查了。在查询前,MySQL肯定要“理解”你这条SQL语句啊,所以要有个“零件”去分析验证你的SQL语句,那究竟是怎么个分析过程呢?
这也是为什么我们的SQL语句存在语法问题的时候会报错,就是这个叫做分析器的零件报出来的。
语法没问题,就够了吗?当然不够,智能的MySQL还要帮我们做优化,那都做哪方面的优化呢?
这个过程就是由MySQL的优化器做的。
优化器阶段完成后,这个语句的执行方案就确定下来了,然后真正的开始执行了。
在执行之前需要判断该用户是否具备权限 。如果没有,就会返回权限错误。如果具备权限,就执行 SQL 查询并返回结果。
我们以一开始的查询语句select * from T where ID =10;
为例,ID没有索引,并且采用的innoDB
作为存储引擎,整体查询的流程如下:
InnoDB
存储引擎接口取这个表的第一行,判断 ID 值是不是1上述遍历过程中所有满足条件的行组成的记录集作为结果集返回给客户,这一个过程就是由MySQL的执行器执行的。
上面讲解了查询语句的真个执行流程,涉及了MySQL的各个“零件”,我们将这些零件组装组装,可以形成下面的逻辑架构图:
大体来说,MySQL可以分为Server层和存储引擎层两部分。
InnoDB
、MyISAM
、Memory
等多个存储引擎。所有的存储引擎都共用同一个Server层。本文通过以一个查询语句的执行流程为例,讲解了MySQL整体的逻辑架构,对MySQL的各个部分有了一个全局的认知。这样,在遇到问题的时候,也比较有针对性,比如对于一个select * from T where k=1
,报了Unknown column ‘k’ in ‘where clause’
的错误,我们就很快的知道是分析器报出来的,因为分析器会分析我们SQL的语法。