一条SQL语句在MySQL中是如何执行的?
副问题[/!--empirenews.page--]
媒介 最近开始在进修mysql相干常识,本身按照学到的常识点,按照本身的领略清算分享出来,本篇文章会说明下一个sql语句在mysql中的执行流程,包罗sql的查询在mysql内部会怎么流转,sql语句的更新是怎么完成的。在说明之前我会先带着你看看 MySQL 的基本架构,知道了 MySQL 由那些组件构成已经这些组件的浸染是什么,可以辅佐我们领略息争决这些题目。 一、mysql架构说明 下面是mysql的一个扼要架构图: ![]() mysql首要分为Server层和存储引擎层 Server层:首要包罗毗连器、查询缓存、说明器、优化器、执行器等,全部跨存储引擎的成果都在这一层实现,好比存储进程、触发器、视图,函数等,尚有一个通用的日记模块 binglog日记模块。 存储引擎: 首要认真数据的存储和读取,回收可以替代的插件式架构,支持InnoDB、MyISAM、Memory等多个存储引擎,个中InnoDB引擎有自有的日记模块redolog 模块。 InnoDB 5.5.5版本作为默认引擎。 毗连器 首要认真用户登录数据库,举办用户的身份认证,包罗校验账户暗码,权限等操纵,假如用户账户暗码已通过,毗连器会到权限表中查询该用户的全部权限,之后在这个毗连里的权限逻辑判定都是会依靠此时读取到的权限数据,也就是说,后续只要这个毗连不绝开,即时打点员修改了该用户的权限,该用户也是不受影响的。 查询缓存 毗连成立后,执行查询语句的时辰,会先查询缓存,Mysql会先校验这个sql是否执行过,以Key-Value的情势缓存在内存中,Key是查询估量,Value是功效集。假如缓存key被掷中,就会直接返回给客户端,假如没有掷中,就会执行后续的操纵,完成后也会把功效缓存起来,利便下一次挪用。虽然在真正执行缓存查询的时辰照旧会校验用户的权限,是否有该表的查询前提。 Mysql 查询不提议行使缓存,由于对付常常更新的数据来说,缓存的有用时刻太短了,每每带来的结果并欠好,对付不常常更新的数据来说,行使缓存照旧可以的,Mysql 8.0 版本后删除了缓存的成果,官方也是以为该成果在现实的应用场景较量少,以是爽性直接删掉了。 说明器 mysql 没有掷中缓存,那么就会进入说明器,说明器首要是用来说明SQL语句是来干嘛的,说明器也会分为几步:
完成这2步之后,mysql就筹备开始执行了,可是怎样执行,怎么执行是最好的功效呢?这个时辰就必要优化器上场了。 优化器 优化器的浸染就是它以为的最优的执行方案去执行(固然偶然辰也不是最优),好比多个索引的时辰该怎样选择索引,多表查询的时辰怎样选择关联次序等。 执行器 当选择了执行方案后,mysql就筹备开始执行了,起首执行前会校验该用户有没有权限,假如没有权限,就会返回错误信息,假若有权限,就会去挪用引擎的接口,返回接口执行的功效。 二、语句说明 2.1 查询语句 说了以上这么多,那么毕竟一条sql语句是怎样执行的呢?着实我们的sql可以分为两种,一种是查询,一种是更新(增进,更新,删除)。我们先说明下查询语句,语句如下:
团结上面的声名,我们说明下这个语句的执行流程: 先搜查该语句是否有权限,假如没有权限,直接返回错误信息,假若有权限,在mysql8.0版本早年,会先查询缓存,以这条sql语句为key在内存中查询是否有功效,假若有直接缓存,假如没有,执行下一步。 通过说明器举办词法说明,提取sql语句的要害元素,好比提取上面这个语句是查询select,提取必要查询的表名为tb_student,必要查询全部的列,查询前提是这个表的id='1'。然后判定这个sql语句是否有语法错误,好比要害词是否正确等等,假如搜查没题目就执行下一步。 接下来就是优化器举办确定执行方案,上面的sql语句,可以有两种执行方案:
那么优化器按照本身的优化算法举办选择执行服从最好的一个方案(优化器以为,偶然辰不必然最好)。那么确认了执行打算后就筹备开始执行了。 举办权限校验,假如没有权限就会返回错误信息,假若有权限就会挪用数据库引擎接口,返回引擎的执行功效。 2.2 更新语句 以上就是一条查询sql的执行流程,那么接下来我们看看一条更新语句怎样执行的呢?sql语句如下:
我们来给张三修改下年数,在现实数据库必定不会配置年数这个字段的,否则要被技能认真人打的。着实条语句也根基上会沿着上一个查询的流程走,只不外执行更新的时辰必定要记录日记啦,这就会引入日记模块了,mysql 自带的日记模块式binlog(归档日记),全部的存储引擎都可以行使,我们常用的InnoDB引擎还自带了一个日记模块redo log,我们就以InnoDB模式下来切磋这个语句的执行流程。流程如下: 先查询到张三这一条数据,假若有缓存,也是会用到缓存。 然后拿到查询的语句,把 age 改为19,然后挪用引擎API接口,写入这一行数据,InnoDB引擎把数据生涯在内存中,同时记录redo log,此时redo log进入prepare状态,然后汇报执行器,执行完成了,随时可以提交。 执行器收到关照跋文录binlog,然后挪用引擎接口,提交redo log 为提交状态。 更新完成。 这里必定有同窗会问,为什么要用两个日记模块,用一个日记模块不可吗?这就是之前mysql的模式了,MyISAM引擎是没有redo log的,那么我们知道它是不支持事宜的,以是并不是说只用一个日记模块不行以,只是InnoDB引擎就是通过redo log来支持事宜的。那么,又会有同窗问,我用两个日记模块,可是不要这么伟大行不可,为什么redo log 要引入prepare预提交状态?这里我们用反证法来声名下为什么要这么做?
(编辑:湖南网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |