作者:编程爬阶小马
对于一个开发工程师来说,了解一下 MySQL 是如何执行一条查询语句的,不是一件坏事,阿粉带你来瞅瞅它是怎么执行的
一条看似非常简单的查询语句:
select * from T where id=1;
然后 MySQL 就返回给了你结果,但是里面具体是如何执行的呢?
别急,听阿粉慢慢跟你说
首先咱们先来看一张图,接下来的过程都是基于这张图来讲的:
连接器
当客户端连接 MySQL 时,会发出连接请求到连接器,连接器此时就会去验证这个连接的账号密码
- 如果账号或者密码不正确,客户端就会收到一个
Access denied for user
的错误,之后此次连接结束 - 账号密码正确,连接器会到权限表里面查询出该账号所拥有的权限,之后这个连接里面的权限判断,都是以此时读到的权限为根据
所以你知道为什么更改了一个账号的权限之后,一定要断开再重连才有效吧~
在实际中肯定有这样的情况,就是一个连接建立之后,但是我没有执行什么操作,那么就可以说这个连接处于空闲状态( sleep )
如果长时间都没有什么操作的话,连接器就会选择把它断开,这个时间是由 wait_timeout 来控制的,默认值是 8 小时
连接都被断开了,如果此时客户端再次发送请求想要进行一些操作的话,那就需要重新建立连接才能往下走
在数据库中有两种连接:
- 短连接:每次执行完很少的几次查询就断开连接,下次想查询时,就要重新建立一个
- 长连接:如果客户端持续有请求,那就一直使用同一个连接
建立连接是比较麻烦的,首先要发送请求吧,发送了请求要去验证账号密码吧,验证完了要去看你所拥有的权限吧,所以在使用过程中,尽量使用长连接
但是使用长连接又有新的问题:有时候,你会发现 MySQL 占用内存,因为是长连接嘛,所以它会在断开的时候才将资源释放掉。
这个时候可以考虑下面两种方案:
- 定期断开长连接
- 如果使用的是 MySQL 5.7 或者更高版本,可以在每次执行一个比较大的操作之后,通过执行 mysql_reset_connection 来重新初始化连接资源,这个过程不需要重新连接和权限验证
分析器
连接器这一关是过来了,接下来就是去查询缓存
首先看缓存里面有没有,如果有呢,那就没有必要向下走,直接返回给客户端结果就可以了
如果缓存中没有的话,那就去分析器
但是聪明的你肯定发现了,我的小标题并不是缓存,而是分析器,为啥呢?
因为查询缓存的失效非常频繁,只要有对一个表的更新,那在这个表上的所有查询缓存都会被清空。所以就会导致 MySQL 费劲吧啦的把缓存给建立起来了,结果呢还没怎么用,一个更新操作,给弄没了
所以 MySQL 8.0 版本直接将查询缓存的整块功能都给删掉了,那么在这里也不细说,免得奇怪的知识增加
分析器首先会进行"词法分析