对于一个做后台不久的我,起初做项目只是实现了功能,所谓的增删改查,和基本查询索引的建立。直到有一个面试官问我一个问题,一条sql查询语句在mysql数据库中具体是怎么执行的?我被虐了,很开心,感谢他。于是开始了深入学习mysql。本篇文章通过
一条sql查询语句在mysql数据库中具体是怎么执行的?
来具体讲解mysql的基础架构。
mysql> select * from Student where ID=1;
上面一条简单的查询语句很简单,但我想好多开发者并不知道在MYSQL内部的执行过程。
Mysql基本架构示意图
从图中可以看出Mysql可以大体分为Server层和存储引擎层两部分。Server层包括连接器、查询缓存、分析器、优化器、执行器等,这些涵盖了MySQL的大多数核心服务和所有的内置函数(如日期、时间、数学和加密函数等),跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图等。
存储引擎层负责数据的存储和提取,提供数据的读写接口。其架构模式是插件式的,支持InnoDB、MyISAM、Memory等多个存储引擎。目前开发中最常用的存储引擎是InnoDB,它从MySQL5.5.5版本开始成为默认存储引擎,不过开发者也可以通过指定存储引擎的类型来选择别的引擎。
即使存储引擎不同,但是也会共用一个Server层,接下来对Server层中的执行流程,依次对其作用进行讲解。
运行查询语句开始查询的前提是第一步先连接数据库,这时候等待你的就是连接器。连接器负责和客户端建立连接、获取权限、维持和管理连接。
常规的开发模式,客户端与服务器需要建立连接。二者在完成经典的TCP握手后,Server层连接器就要开始认证你的身份,这个时候是服务器端代码使用的用户名和密码。
连接器一些内容说明:
mysql>show processlist
较好的连接方式长连接产生的问题以及解决办法:
全部使用长连接后,你可能会发现,有些时候 MySQL 占用内存涨得特别快,这是因为 MySQL 在执行过程中临时使用的内存是管理在连接对象里面的。这些资源会在连接断开的时候才释放。所以如果长连接累积下来,可能导致内存占用太大,被系统强行杀掉(OOM),从现象看就是 MySQL 异常重启了。怎么解决这个问题呢?你可以考虑以下两种方案。
第一步连接建立完成后,就可以执行查询语句了。第二步,查询缓存。 Mysql确定了查询语句,会先到查询缓存中,看之前是否执行过这条查询语句。之前如果执行过这条查询语句,查询结果可能会以key-value的方式直接缓存在内存中。key是查询的语句,value是查询到的值,这样的话查询缓存会直接把value值返回给客户端。查询语句如果步子查询缓存中,会正常往下执行,获取到新的查询结果后会被存入到查询缓存中。
说明:
mysql> select SQL_CACHE * from Student where ID=1;
注意:
Mysql 8.0版本直接将查询缓存对整块功能删除掉了,8.0之后将不再出现查询缓存。
如果在查询缓存中未找到缓存数据,就会开始真正的执行查询语句。Mysql需要直到这条查询语句要做什么?因此需要对SQL语句做解析。
解析流程:
mysql> select * from Student where ID=1;
mysql> elect * from Student where ID=1;
ERROR 1064 (42000) You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'elect * from t where ID=1' at line 1
分析器执行之后,到达了优化器。
优化器会做那些优化处理:
mysql> select * from t1 join t2 using(ID) where t1.c=10 and t2.d=20;
复制代码
MySQL 通过分析器知道了你要做什么,通过优化器知道了该怎么做(执行方案是什么?),于是就进入了执行器阶段,开始执行语句。
开始执行的时候,要先判断一下你对这个表 Student 有没有执行查询的权限,如果没有,就会返回没有权限的错误,如下所示 (在工程实现上,如果命中查询缓存,会在查询缓存返回结果的时候,做权限验证。查询也会在优化器之前调用 precheck 验证权限)。
mysql> select * from Student where ID=10;
ERROR 1142 (42000): SELECT command denied to user 'b'@'localhost' for table 'Student'
如果有权限,就打开表继续执行。打开表的时候,执行器就会根据表的引擎定义,去使用这个引擎提供的接口。
来到存储引擎,执行存储引擎提供的数据读写接口。 这条查询语句,执行器(注意这里读写数据的还是存储引擎)读写数据的流程要分两种情况考虑:
到此,一条查询语句在mysql架构中执行基本流程进行了一个大概的讲解。在这个流程中,会有很多细节和可深挖学习的地方,例如关联(join)、索引、日志系统等,接下来会继续学习并记录一些MySql深入的东西。
更多资料展示如下,需要的小伙伴们转发,私信口令:资料,即可获得以下资料!!!
留言与评论(共有 0 条评论) |