下面我给出的是 MySQL 的基本架构示意图,从中你可以清楚地看到 SQL 语句在 MySQL 的各个功能模块中的执行过程。
从图中可以看出,不同的存储引擎公用一个server层。
连接器
-
连接命令
mysql -h$ip -P$port -u$user -p
-
连接保持时间
-
连接完成之后,如果没有后续的动作,这个连接就会处于空闲状态,可以在
show processlist
命令中看到。 -
客户端如果太长时间没有动静,连接器会主动将其断连。这个参数是wait_timeout控制的,默认时间是8小时。
-
断开之后再发送请求的话,就会收到一个错误提醒:Lost connection to MySQL server during query。需要客户端重新连接,然后再发送请求。
-
-
长连接占用内存问题
- 在执行过程中,连接中使用的内存是管理在连接对象里面的。这些资源只有在断连的时候才会释放。这些长连接累积下来,可能会导致内存占用越来越大,最终被系统OOM掉。
- 解决:
- 定期断开连接。使用一段时间以后,或者在程序里面判断执行过一个比较大的操作之后,重新连接。
- 或者可以在执行过一个较大的操作之后,执行mysql_reset_connection来重新初始化连接资源。
查询缓存
建立连接之后,进行select语句查询,就会进入查询缓存阶段。每次的查询会把结果放入缓存,下次有相同的查询会直接在缓存中获取即可,无需进入存储引擎进行查询。
但是,查询缓存这个事情是弊大于利的,所以不会建议使用。mysql8.0之后直接将该模块删除了。
为啥有弊呢?因为每次存在update操作的情况下,就会把整个缓存都清除掉,导致缓存命中率特别低。
在8.0之前的版本,可以直接将query_cache_type设置为DEMAND,这样的话,查询语句默认不使用缓存。在需要使用查询缓存的地方可以显示调用。mysql> select SQL_CACHE * from T where ID=10;
分析器
分析器先做“词法分析”,根据语法规则,判断输入的sql语句是否满足mysql语法规则。
优化器
优化器是在表中存在多个索引的情况下,决定用哪个索引;或者在一个语句有多表关联(join)的时候,决定各个表的连接顺序。
执行器
MySQL通过分析器知道了你要做什么,通过优化器知道了该怎么做,于是就进入了执行器阶段,开始执行语句。