目录
概括
MySQL基本架构示意图:
大体来说,MySQL可以分为Server层和存储引擎层两部分。
Server层包括连接器、查询缓存、分析器、优化器、执行器等,涵盖MySQL大多数核心服务功能,以及所有的内置函数(如日期、时间、数学和加密函数等),所有跨引擎的功能都在这一层实现,比如存储过程、触发器、视图等。
存储引擎层负责数据的存储很提取。其架构模式是插件式的,支持InnoDB、MyISAM、Memory等多个存储引擎。现在最常用的存储殷勤是InnoDB,它从MySQL5.5.5版本开始成为默认存储引擎。
连接器
第一步,会先连接到数据库上,这时候接待你的就是连接器。连接器负责跟客户端建立连接、获取权限、维持和管理连接。
连接完成后,如果你没有后续动作,这个连接就处于空闲状态,可以通过show processlist命令中看到它。Sleep这行表示现在系统里面有一个空闲连接,如下(这是我使用我本地数据库的查询结果):
客户端太长时间没有动静,连接器就会自动将它断开,默认是8小时,这个时间是由参数wait_timeout控制的。断开后客户端如果再次发送请求的话,就会收到一个错误提醒:Lost connection to MySQL server during query。这时候如果要继续,就需要重新连接。
数据库中的长连接、短连接。
连接数据库耗时,建议尽量使用长连接,但是长连接会使得MySQL的内存涨的特别快,可能会导致异常重启。解决办法:1、定期断开长长连接;2、如果使用的是MySQL5.7或者更新版本,可以在需要的时候执行mysql_reset_connection来重新初始化连接资源,这个过程需要重连和重新做权限验证,但是会将连接状态恢复至刚刚创建完成时的状态。
查询缓存
连接建立完成后,就可以执行select语句了。执行逻辑来到第二部:查询缓存。如果缓存存在,直接返回。如果缓存不存在,就会继续执行后面的执行阶段,执行完后,执行结果会被存入查询缓存。
但是大多数情况下建议不要使用查询缓存,因为查询缓存往往弊大于利。
查询缓存的失效率非常频繁,只要有对一个表的更新,这个表上所有的查询缓存都会被清空。除非静态表,几乎不做更新。
MySQL也提供了参数可以设置是否使用缓存,可以将参数query_cache_type设置成DEMANT,这样默认都不使用查询缓存。对于确定要使用查询缓存的可以这样使用:SELECT SQL_CACHE * FROM T WHERE ID=10;
需要注意的是,MySQL8.0版本将整个查询缓存功能删除掉了。
分析器
词法分析、语法分析
先做词法分析,识别关键字、表名、列
然后做语法分析、是否符合MySQL语法
优化器
经过分析器,MySQL就知道你要做什么了。然后还要经过优化器的处理。
优化器是在表里面有多个索引的时候,决定使用哪个索引;或者有多表关联的时候,决定各个表的连接顺序。
优化器执行完后,这个语句的执行方案就确定下来了,然后进入执行器阶段。
执行器
MySQL经过分析器知道了你要做什么,经过优化器知道了怎么做,于是就进入了执行器阶段,开始执行语句。
开始执行的时候,要先判断你对当前表有没有执行查询的权限,如果没有就会返回没有权限的错误。
如果有权限,就打开表继续执行,一行一行的扫描表中数据,将符合条件的结果放入结果集中,知道表中最后一行数据,最后将结果集返回给客户端。
至此,一个sql查询语句就执行完了。
问题:为什么对权限的检查不在优化器之前做?
有些时候,SQL语句要操作的表不只是SQL字面上那些,比如有个触发器,得在执行器阶段才能确定,优化器阶段是无能为力的。
下一篇:02 | 日志系统:一条SQL更新语句是如何执行的 (总结)