截取一张丁奇大佬画的架构图
MySQL大致可以分为Server层和存储引擎层两部分。
Server层包括连接器、查询缓存、分析器、优化器、执行器等,涵盖MySQL的大多数服务功能,
以及所有的内置函数,所有跨存储引擎的功能都在这一层实现,比如存储过程、视图等。
存储引擎层负责数据的存储和提取。支持InnoDB,MyISAM,Memory等多个存储引擎
从MySQL5.5.5开始默认存储引擎为InnoDB。
接下来根据下面的这条sql语句,依次观看每个组件的作用。
mysql> select * from T where ID=10 ;
第一步,你会连接到这个数据库上,接待你的就是连接器,连接器负责和客户端建立连接、获取权限、维持和管理连接。连接命令如下:
mysql -h ip地址 -P 端口号 -u 用户名 -p
执行命令后,输入密码。
连接命令中的mysql是客户端工具,用来跟服务器建立连接。完成经典的TCP握手后,连接器就会使用你输入的用户名和密码认证你的身份。
连接完成后,如果你没有后续动作,这个连接处于空闲状态,你可以使用show processlist命令查看。
客户端如果太长时间没有动作,连接器就会自动将它断开,这个时间由参数wait_timeout设置,默认是8小时。
数据库里,长连接是指连接成功后,如果客户端持续有请求,则一直使用同一个连接。短连接是指每次执行完很少的几次查询就断开,下次查询再重新建立。
建立连接过程较复杂,尽量使用长连接,但是全部使用长连接,你有时会发现MySQL涨的特别快,这是因为
MySQL在执行过程中临时使用的内存是管理在连接对象里的,连接断开的时候才会释放资源,如果长连接累积下来可能造成内存占用太多,被系统强行杀掉,从现象看就是MySQL异常重启了。
那么怎么解决这个问题呢?
1.定时断开长连接。使用一段时间,或程序里判断执行过一个占用内存的大查询后,断开连接,之后重连。
2.如果版本是5.7以上版本,可以在每次执行比较大的操作后,通过mysql_reset_connect来重新初始化连接资源。这个过程不需要重连和重新做权限验证,连接会恢复到刚创建完的状态。
连接建立后,就可以执行select语句了,执行逻辑会来到第二步:查询缓存。
mysql拿到查询请求后,会先到查询缓存看看,之前是否执行过这条语句。之前执行过的语句可能会以key-value对的形式缓存在内存中。key是查询的语句,value是查询的结果。如果你的查询能够在查询缓存中找到匹配的,那么对应的value会直接返回给客户端。
如果语句不在查询缓存中,就会继续后面的执行阶段。执行完成后,执行结果会存入查询缓存中,如果查询命中缓存,mysql不需要执行后面的复杂操作就能直接返回结果,效率很高。
但是大多数情况建议不要使用查询缓存?
因为弊大于利,查询缓存的失效非常频繁,只要有对一个表的更新,这个表上的所有查询缓存都会被清空。对于更新压力大的数据库,查询缓存的命中率会非常低。除非你的业务是一张静态表,很长时间才更新一次,比如:系统配置表,那么这张表上的查询才适合使用查询缓存。
配置方式:将参数query_cache_type设置成DEMAND,这样对于默认的sql语句都不使用查询缓存。对于确定要使用的语句,可以用 SQL_CACHE显示指定,范例如下:
select SQL_CACHE * from S where sid = 1;
注意8.0版本开始,查询缓存的整块功能都被删掉了。
如果没有命中缓存就开始真正执行语句了。
首先要想让mysql知道你要做什么,因此需要对MySQL语句做解析。
分析器首先做“词法分析”。识别出里面的字符串分别是什么,代表什么。
接下来进行语法分析。根据语法分析的规则,判断SQL语句是否符合语法格式。
经过了分析器,MySQL就知道你要做什么了。在开始执行之前,还要先经过优化器的处理。
优化器是在表里有多个索引时,决定使用哪个索引;或者一个语句有多表关联时,决定各表的连接顺序。
不同的执行方法效率不同,逻辑结果相同,优化器的作用就是决定使用哪一个方案。
经过优化器的优化后,进入执行阶段,执行器开始执行语句。
开始执行的时候,先要判断你对这个表有没有执行某个操作的权限,
如果有权限,就打开表继续执行。打开表的时候,执行器会根据表的引擎定义,去使用这个引擎提供的接口执行操作。