百分百源码网-让建站变得如此简单! 登录 注册 签到领金币!

主页 | 如何升级VIP | TAG标签

当前位置: 主页>网站教程>数据库> 剖析SQL查询语句是怎样施行的
分享文章到:

剖析SQL查询语句是怎样施行的

发布时间:09/01 来源:未知 浏览: 关键词:

第一有一个 user_info 表,表里有一个 id 字段,施行下面这条查询语句:

select * from user_info where id = 1;

返回结果为:

ea3bfe74158de0a086f8cdb71d7522b.png

mysql根本架构示企图:

fe5ba5d012ebaaed8d389c7516429d0.png

(相关视频教程引荐:mysql视频教程)

大体上,MySQL 分为 Server 层和储备引擎层两部分。

Server 层包罗连接器、查询缓存、剖析器、施行器等,乃至所有的内置函数(如日期、时间、数学和加密函数等)和跨储备引擎的功效(如储备历程、触发器、视图)。

储备引擎层负责数据的储备和提取,支撑 InnoDB、MyISAM、Memory 等多个储备引擎。MySQL 5.5.5 版本后默许储备储备引擎是 InnoDB。

连接器(Connector)

在查询 SQL 语句前,必定要先创立与 MySQL 的连接,这就是由连接器来完成的。连接器负责跟客户端创立连接、猎取权限、保持和治理连接。连接命令为:

mysql -h$ip -P$port -u$user -p

输入密码,验证通过后,连接器会到权限表里面查出你具有的权限,之后这个连接里面的权限推断逻辑,都将依靠于此时读到的权限,一个会员成功创立连接后,即便治理员对这个会员的权限做了修改,也不会影响已经存在连接的权限,修改完后,只要再创建的连接才会使用新的权限设定。

连接完成后,假如你没有后续的动作,这个连接就处于余暇状态,你可以在 show processlist 命令中看到它。结果如下:

8fba24335808f3a3d27ac08a1bb6b79.png

客户端假如太长时间没动静,连接器就会主动将它断开;这个时间是由参数 wait_timeout 操纵的,默许值是8小时。假如在连接被断开之后,客户端再次发送恳求的话,就会收到一个错误提示:Lost connection to MySQL server during query

长连接和短连接

数据库里面,长连接是指连接成功后,假如客户端连续有恳求,则不断使用统一个连接。短连接则是指每次施行完很少的几次查询就断开连接,下次查询再从新创立一个。

创立连接的历程平常是比力复杂的,倡议在使用中要尽量减少创立连接的动作,尽量使用长连接。但是全部使用长连接后,有时候 MySQL 占用内存涨得特殊快,这是由于 MySQL 在施行历程中暂时使用的内存是治理在连接对象里面的。

这些资源会在连接断开的时候才开释。所以假如长连接累积下来,大概致使内存占用太大,被系统强行杀掉(OOM),从现象看就是 MySQL 非常重新启动了。

如何解决这个问题呢?可以思考以下两种方案:

按期断开长连接。使用一段时间,或者程序里面推断施行过一个占用内存的大查询后,断开连接,之后要查询再重连。MySQL 5.7 以上版本,可以在每次施行一个比力大的操纵后,通过施行 mysql_reset_connection 来从新初始化连接资源。这个历程不需要重连和从新做权限验证,但是会将连接复原到刚刚创立完时的状态。

查询缓存(Query Cache)

在创立连接后,就开端施行 select 语句了,施行前第一会查询缓存。

MySQL 拿到查询恳求后,会先查询缓存,看是不是施行过这条语句。施行过的语句及其结果会以 key-value 对的情势留存在必然的内存区域中。key 是查询的语句,value 是查询的结果。假如你的查询能够直接在这个缓存中寻到 key,那么这个
value 就会被直接返回给客户端。

假如语句不在查询缓存中,就会连续后面的施行阶段。施行完成后,施行结果会被存入查询缓存中。假如查询命中缓存,MySQL 不需要施行后面的复杂操纵,就可以直接返回结果,会晋升效力。

但是查询缓存的失效非常频繁,只要有对一个表的更新,这个表上所有的查询缓存都会被清空。关于更新压力大的数据库来说,查询缓存的命中率会非常低。假如业务中需要有一张静态表,很长时间才会更新一次。

比方,一个系统配置表,那这张表上的查询才适合使用查询缓存。MySQL 供给了这种按需使用的方式。可以将参数 query_cache_type 设定成 DEMAND,关于默许的 SQL 语句都将不使用查询缓存。而关于你肯定要使用查询缓存的语句,可以用 SQL_CACHE 显式指定,如下:

mysql> select SQL_CACHE * from user_info where id = 1;

MySQL 8.0 版本将查询缓存的功效删除了。

剖析器(Analyzer)

假如查询缓存未命中,就要开端施行语句了。第一,MySQL 需要对 SQL 语句停止解析。

剖析器先会做词法剖析。SQL 语句是由多个字符串和空格组成的,MySQL 需要识别出里面的字符串离别是啥,代表什么。MySQL 从你输入的 select 这个关键字识别出来,这是查询语句。它也要把字符串 user_info 识别成表名,把字符串 id 识别成列名。之后就要做语法剖析。按照词法剖析的结果,语法剖析器会按照语律例则,推断输入的 SQL 语句可否知足 MySQL 语法。

假如你 SQL 语句不合错误,就会收到 You have an error in your SQL syntax 的错误提示,比方下面这个语句 from 写成了 form。

mysql> select * form user_info  where id = 1;
1064 - 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 'form user_info  where id = 1' at line 1

一样语法错误解提醒第一个显现错误的位置,所以要关注的是紧接 use near 的内容。

优化器(Optimizer)

经过剖析器的词法剖析和语法剖析后,还要经过优化器的处置。

优化器是在表里面有多个索引的时候,决议使用哪个索引;或者在一个语句有多表关联(join)的时候,决议各个表的连接次序。比方你施行下面这样的语句,这个语句是施行两个表的 join:

mysql> SELECT * FROM order_master JOIN order_detail USING (order_id) WHERE order_master.pay_status = 0 AND order_detail.detail_id = 1558963262141624521;

既可以先从表 order_master 里面取出 pay_status = 0 的记载的 order_id 值,再按照 order_id 值关联到表 order_detail,再推断 order_detail 里面 detail_id 的值可否等于 1558963262141624521。

也可以先从表 order_detail 里面取出 detail_id = 1558963262141624521 的记载的 order_id 值,再按照 order_id 值关联到 order_master,再推断 order_master 里面 pay_status 的值可否等于 0。

这两种施行办法的逻辑结果是一样的,但是施行的效力会有不一样,而优化器的作用就是决议选中使用哪一个方案。优化器阶段完成后,这个语句的施行方案就肯定下来了,然后进入施行器阶段。

施行器(Actuator)

MySQL 通过剖析器知道了要做什么,通过优化器知道了该如何做,于是就进入了施行器阶段,开端施行语句。

开端施行的时候,要先推断一下你对这个表 user_info 有没有施行查询的权限,假如没有,就会返回没有权限的错误,如下所示 (假如命中查询缓存,会在查询缓存返回结果的时候,做权限验证。查询也会在优化器此前调取 precheck 验证权限)。

mysql> select * from user_info where id = 1;ERROR 1142 (42000): SELECT command denied to user 'wupx'@'localhost' for table 'user_info'

假如有权限,就翻开表连续施行。翻开表的时候,施行器就会按照表的引擎定义,去使用这个引擎供给的接口。比方我们这个例子中的表 user_info 中,id 字段没有索引,那么施行器的施行流程是这样的:

1、调取 InnoDB 引擎接口取这个表的第一行,推断 id 值是不是 1,假如不是则跳过,假如是则将这行存在结果集中;

2、调取引擎接口取下一行,反复雷同的推断逻辑,直到取到这个表的最后一行。

3、施行器将上述遍历历程中所有知足前提的行组成的记载集作为结果集返回给客户端。

关于有索引的表,第一次调取的是取知足前提的第一行这个接口,之后轮回取知足前提的下一行这个接口。

数据库的慢查询日志中有 rows_examined 字段,表示这个语句施行历程中扫描了多少行。这个值就是在施行器每次调取引擎猎取数据行的时候累加的。在有些场景下,施行器调取一次,在引擎内部则扫描了多行,因此引擎扫描行数跟 rows_examined 并不是完全雷同的。

总结

主要通过对一个 SQL 语句完全施行历程停止讲解,介绍 MySQL 的逻辑架构,MySQL 主要包罗连接器、查询缓存、剖析器、优化器、施行器这几个模块。

相关文章教程引荐:mysql教程

以上就是剖析SQL查询语句是怎样施行的的具体内容,更多请关注百分百源码网其它相关文章!

打赏

打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

百分百源码网 建议打赏1~10元,土豪随意,感谢您的阅读!

共有151人阅读,期待你的评论!发表评论
昵称: 网址: 验证码: 点击我更换图片
最新评论

本文标签

广告赞助

能出一分力是一分吧!

订阅获得更多模板

本文标签

广告赞助

订阅获得更多模板