一条sql查询语句是如果执行的?
总体来说,MySQL大致分为server层和存储引擎层两大部分。
1 | explain SELECT * FROM T |
Server层
包括连接器、查询缓存、分析器、优化器、执行器等,所有跨存储引擎的功能都在这一层实现,例如:存储过程、触发器、视图等。
连接器
1.客户端与服务端建立连接,完成tcp三次握手之后,就执行ACL鉴权;
2.连接成功后,可通过:show processlist;
来查看连接状态;
3.尽量使用长连接;
4.连接断开才会释放资源;
5.如果不断的建立连接,会占用太多的内存,导致OOM(内存溢出),会被系统强制kill掉,这种情况就是MySQL异常重启了;
6.上诉5的解决方案:1.定期断开连接,按需重连;2.MySQL5.7+版本,可通过:mysql_reset_connection
来重新初始化连接资源,这个过程不需要重新ACL鉴权,而是会直接回到最初的连接状态。
查询缓存
1.k-v对的形式缓存,即是:查询语句+查询结果;
2.基本就是getOrSet的过程,找得到直接返回,找不到则执行查询,将执行结果缓存起来;
3.不能滥用SQL_CACHE,每次更新会清空建立的缓存,静态表推荐使用,频繁更新的不推荐使用,后者命中缓存的几率很低,基本都是走执行过程了。
分析器
举例子简单的sql语句:select * from T where id = 1;
1.词法分析。MySQL会从输入的语句中的’select’这个关键字做识别,认为这是一条查询语句,继续会被T解析成表名T,id则会被识别为列ID;
2.语法分析。通过一系列的语法去检验sql语句是否满足MySQL的语法要求,如果语法错误则会出现SQL syntax error
错误;
优化器
select * from t1 join t2 using(ID) where t1.c=10 and t2.d=20;
1.决定使用哪个索引;
2.决定连接顺序,确认用哪种执行方案。例如:先查t1后t2,先t2后t1,这里方案是一致的,但是效率可能不同。
3.进入执行阶段;
执行器
分析器已经告诉你了需要查询还是更新,优化器也决定了使用哪种方案,然后就准备执行语句了。
1.判断是否有执行查询语句权限;
2.在工程上,如果命中了缓存,会在返回结果前做权限验证,查询也会在优化器前做precheck验证权限。
3.如果有权限,那么就开始打开表,执行器会根据表定义的engine引擎,使用这个引擎提供的查询接口。
存储引擎
主要是负责数据的存储以及提取咯。其架构是插件式的,支持InnoDB、MyISAM、Memory等多个存储引擎,mysql v-5.5.5版本,InnoDB开始成为了默认的引擎。
可以通过:engine=存储引擎 的方式来指定存储引擎。