这是我第一次写博客,写的不好希望大家指正(说实话,有点紧张)。
今天我们要把MySql的内部"拆解"开来,通过了解MySql内部当我们发生问题时能够更快速的定位到问题。
下面是MySql的基本架构示意图,从图中可以观察到SQL语句在MySql中的执行过程
连接器:提供与客户端连接的服务。对用户输入的用户名和密码进行校验。
- 如果用户名或密码不正确,就会提示"Access denied for user"的错误,随后客户端程序结束。
- 如果通过用户名密码通过验证,则连接器就会到权限表中查出你的权限,以后这个连接的权限都和此时读到的权限相同。
这就意味着,一个用户建立了连接后,即使你使用管理员账号对这个用户的权限进行修改,也不会影响已经存在连接的权限。修改后,只能新建连接才能使用新的权限。
当客户端长时间没动静,连接器就会自动将其断开(默认为8小时,通过show global variables like ‘wait_timeout’;查看全局时间)。这个时间是由wait_timeout控制。
连接完成后,如果没有进行操作,则这个连接就处于空闲状态,使用show processlist;可以查看连接状态。如下图,其中command列显示为sleep则为空闲连接。
查询缓存:MySql内置的一种缓存机制,比如我们进行select * from student查询,当缓存中有匹配的数据并且未过期时就会将数据直接返回。而对sql的匹配规则就是当作字符串比较,如果相同则认为是同一个查询。当没有配的数据则到磁盘中查询,并将查询结果放入缓存中。
如果对一张表进行更新操作,那么这张表的缓存就会清空,所以查询缓存的命中率就会变低。所以要注意的是对于更新频繁的表尽量不要使用缓存,尽量静态表使用。
对于Mysql可以将参数 query_cache_type设置成demand,这样对于默认的sql就不使用查询缓存,当你要使用时,使用SQL_CACHE显示指定。
例如:select SQL_CACHE * from T where id = xxx;
注意:MySql8.0版本中直接将查询缓存功能删除了。
分析器:
(1)词法分析:分析sql语句的关键词。比如将字符串"T"转换成表T,对应的字符串转换成列。
(2)语法分析:sql格式是否正确,比如: elect * from T;
优化器:对sql进行优化。优化器对sql语句进行合适的索引选择;或者当有连接查询时,决定表的连接顺序。比如:
select * from t1 join t2 where t1.id=3 and t2.id=4;
这种情况下我们可以先从他表中找id为3的值,也先可以找t2表中id为4的值。而结果虽然一样,但是执行效率却很不同。优化器会对先去执行哪个进行选择。
执行器:
优化器优化后,进入执行器,开始执行语句。
开始执行的时候,要先判断下是否有执行查询的权限,没有的话就返回没有权限的错误(查询缓存时也要进行权限的校验)
select * from t1 where c=1;
如果上面的sql语句中c字段不是索引,则执行流程如下:
- 调用引擎接口获取这个表的第一行,判断c字段是否是1,如果是则将其放到结果集中,如果不是则跳过
- 再次调用引擎接口获取表的下一行,再次进行判断,知道遍历到最后一行。
- 执行器将结果集返回给客户端。
语句执行结束。
来源:CSDN
作者:不正经的“常春藤”
链接:https://blog.csdn.net/weixin_41624318/article/details/104613404