首先从下面的图中概览整个mysql的结构。
存储引擎是插件式的架构,负责数据的存储和提取,所有夸存储引擎的操作都在server层。
接下来便从一条查询语句的执行流程来介绍这些组件。
连接器
首先需要连接数据库上,而连接器就是负责与客户端建立连接、获取权限、维持和关联连接。
建立tcp连接,验证用户名和密码是否通过,然后再查询用户权限,之后这个连接的所有权限判断逻辑都依赖此时读取到的权限。也就是说,一个用户建立连接后,对这个用户的权限进行修改,修改后的信息只会在新的连接中生效。
连接建立后没有动作就会处于sleep状态,太长时间没有操作连接器就会将其断开,这个时由wait_timeout参数控制,默认是8小时。断开之后想要操作就需要进行重连。
为了减少建立连接的耗时,推荐使用长连接。但是长连接存在一个问题,那就是:Mysql执行过程中临时使用的内存是管理在连接对象中的,所以长连接长时间不释放会导致内存占用率高。而解决这个问题的方案由两种:
- 定期断开长连接。
- mysql5.7及以上版本,可以在每次执行一个较大的操作之后,通过执行mysql_reset_connection来重新初始化连接资源。将连接恢复到刚创建完成的状态。
查询缓存
这里会将执行过的查询语句与查询结果以键值对的形式存储起来。建立连接之后,可以先去查询缓存中查看这个语句是否执行过,如果执行过直接取出结果即可。不需要后续的执行阶段了。
但是,不推荐使用查询缓存。 因此查询缓存的失效非常频繁,只要对一个表有更新,那么这个表上的所有查询缓存就都会失效。所以对于更新压力大的数据库来说查询缓存的命中率非常低。因此除非是一张静态表,很长时间才会更新一次,否则不推荐使用查询缓存。
将参数query_cache_type设置成DEMAND,这样对于默认的sql语句都不使用查询缓存,确认使用查询缓存的使用SQL_CACHE指定:mysql> select SQL_CACHE * from T where ID=10;。
而mysql8.0开始,更是直接将查询缓存移除了。
分析器
分析器首先进行词法分析,辨识出里面的字符串分别是什么,代表什么。 然后对词法分析的结果进行语法分析,判断输入的sql语句是否满足sql语法。
错误的语法会提示第一个错误的位置,所以只需要关注use near的地方。
优化器
在分析器明白了sql语句的作用之后,真正执行之前还需要优化器进行优化。
比如表里有多个索引的时候使用哪个索引比较好;进行多表关联的时候,各个表的连接顺序; 优化器就是选择最优的方案,来保证执行的效率。
执行器
通过分析器知道了做什么,优化器知道了怎么做之后,就是进行执行器开始执行语句了。
首先判断有没有此操作的权限,没有权限直接返回错误。有权限之后才去执行。而执行过程中就是不断调用存储引擎的接口来获取数据。然后将符合条件的行组成结果集返回给客户端。