<small id='MsNa2Kj'></small> <noframes id='7DLP'>

  • <tfoot id='QqhjlfL'></tfoot>

      <legend id='5IcvFs'><style id='nMpdB'><dir id='1bykt'><q id='OHVWSDK4'></q></dir></style></legend>
      <i id='wGjQJuzM'><tr id='xjG4t'><dt id='t5ZgGeCu'><q id='JUQEu7C'><span id='0FflDhJnB'><b id='BswuK'><form id='d0aCKXUwY'><ins id='uYblF0OV'></ins><ul id='xMo8'></ul><sub id='A5IT2qvlm'></sub></form><legend id='5leYS'></legend><bdo id='eDTIoPuxN'><pre id='ntBxEfP'><center id='wKDqUTf2to'></center></pre></bdo></b><th id='vqOeH95Zkt'></th></span></q></dt></tr></i><div id='6h5v38'><tfoot id='ZxhRluJ'></tfoot><dl id='AhTU'><fieldset id='TqxDYcP'></fieldset></dl></div>

          <bdo id='WpJowzRKT'></bdo><ul id='jDKBhPtvMG'></ul>

          1. <li id='NRu39Zc5'></li>
            登陆

            一条 SQL 句子在 MySQL 中是怎么履行的?

            admin 2019-05-14 222人围观 ,发现0个评论
            • 前语
            • 一、mysql架构剖析
            • 二、句子剖析
            • 2.1 查询句子
            • 2.2 更新句子
            • 三、总结

            前语

            最近开端在学习mysql相关常识,自己依据学到的常识点,依据自己的了解收拾共享出来,本篇文章会剖析下一个sql句子在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句子是来干嘛的,剖析器也会分为几步:

            第一步,词法剖析,一条SQL句子有多个字符串组成,首要要提取要害字,比方select,提出查询的表,提出字段名,提出查询条件等等。做完这些操作后,就会进入第二步。

            第二步,语法剖析,首要便是判别你输入的sql是否正确,是否契合mysql的语法。

            完结这2步之后,mysql就预备开端履行了,可是怎样履行,怎样履行是最好的成果呢?这个时分就需求优化器上场了。

            优化器

            优化器的效果便是它以为的最优的履行计划去履行(尽管有时分也不是最优),比方多个索引的时分该怎样挑选索引,多表查询的时分怎样挑选相关次序等。

            履行器

            当挑选了履行计划后,mysql就预备开端履行了,首要履行前会校验该用户有没有权限,假如没有权限,就会回来错误信息,假如有权限,就会去调用引擎的接口,回来接口履行一条 SQL 句子在 MySQL 中是怎么履行的?的成果。

            二、句子剖析

            2.1 查询句子

            说了以上这么多,那么终究一条sql句子是怎样履行的呢?其实咱们的sql能够分为两种,一种是查询,一种是更新(添加,更新,删去)。咱们先剖析下查询句子,句子如下:

            select * from tb_student A where A.age='18' and A.name='张三';

            结合上面的阐明,咱们剖析下这个句子的履行流程:

            • 先查看该句子是否有权限,假如没有权限,直接回来错误信息,假如有权限,在mysql8.0版别曾经,会先查询缓存,以这条sql句子为key在内存中查询是否有成果,假如有直接缓存,假如没有,履行下一步。
            • 经过剖析器进行词法剖析,提取sql句子的要害元素,比方提取上面这个句子是查询select,提取需求查询的表名为tb_student,需求查询一切的列,查询条件是这个表的id='1'。然后判别这个sql句子是否有语法错误,比方要害词是否正确等等,假如查看没问题就履行下一步。
            • 接下来便是优化器进行确认履行计划,上面的sql句子,能够有两种履行计划:
            a.先查询学生表中姓名为“张三”的学生,然后判别是否年纪是18。
            b.先找出学生中年纪18岁的学生,然后再查询姓名为“张三”的学生。
            • 那么优化聂小倩器依据自己的优化算法进行挑选履行功率最好的一个计划(优化器以为,有时分不一定最好)。那么确认了履行计划后就预备开端履行了。
            • 进行权限校验,假如没有权限就会回来错误信息,假如有权限就会调用数据库引擎接口,回来引擎的履行成果。

            2.2 更新句子

            以上便是一条查询sql的履行流程,那么接下来咱们看看一条更新句子怎样履行的呢?sql句子如下:

            update tb_student A set A.age='19' where A.name='张三';

            咱们来给张三修正下年纪,在实践数据库必定不会设置年纪这个字段的,否则要被技能担任人打的。其实条句子也根本上会沿着上一个查询的流程走,只不过履行更新的时分必定要记载日志啦,这就会引进日志模块了,mysql 自带的日志模块式binlog(归档日志),一切的存储引擎都能够运用,咱们常用的InnoDB引擎还自带了一个日志模块redo log,咱们就以InnoDB形式下来讨论这个句子的履行流程。流程如下:

            • 先查询到张三这一条数据,假如有缓存,也是会用到缓存。
            • 然后拿到查一条 SQL 句子在 MySQL 中是怎么履行的?询的句子,把 age 改为19,然后调用引擎API接口,写入这一行数据,InnoDB引擎把数据保存在内存中,一起记载redo log,此刻redo log进入prepare状况,然后告诉履行器,履行完结了,随时能够提交。
            • 履行器收到告诉后记载binlog,然后调用引擎接口,提交redo log 为提交状况。
            • 更新完结。

            这儿必定有同学会问,为什么要用两个日志模块,用一个日志模块不行吗?这便是之前mysql的形式了,MyISAM引擎是没有redo log的,那么咱们知道它是不支撑业务的,所以并不是说只用一个日志模块不能够,仅仅InnoDB引擎便是经过redo log来支撑业务的。那么,又会有同学识,我用两个日志模块,可是不要这么杂乱行不行,为什么redo log 要引进prepare预提交状况?这儿咱们用反证法来阐明下为什么要这么做?

            • 先写redo log 直接提交,然后写 binlog,假定写完redo log 后,机器挂了,binlog日志没有被写入,那么机器重启后,这台机器会经过redo log康复数据,可是这个时分bingog并没有记载该数据,后续进行机器备份的时分,就会丢掉这一条数据,一起主从同步也会丢掉这一条数据。
            • 先写binlog,然后写redo log,假定写完了binlog,机器反常重启了,因为没有redo log,本机是无法康复这一条记载的,可是binlog又有记载,那么和上面相同的道理,就会发生数据不一致的状况。

            假如选用redo log 两阶段提交的方法就不相同了,写完binglog后,然后再提交redo log就会避免呈现上述的问题,然后确保了数据的一致性。那么问题来了,有没有一个极点的状况呢?假定redo log 处于预提交状况,binglog也现已写完了,这个时分发生了反常重启会怎样样呢? 这个就要依靠于mysql的处理机制了,mysql的处理进程如下:

            • 判别redo log 是否完好,假如判别是完好的,就当即提交。
            • 假如redo log 仅仅预提交但不是commit状况,这个时分就会去判别binlog是否完好,假如完好就提交 redo log, 不完好就回滚业务。

            这样就处理了数据一致性的问题。

            三、总结

            • Mysql 首要分为Server曾和引擎层,Server层首要包含衔接器、查询缓存、剖析器、优化器、履行器,一起还有一个日志模块(binlog),这个日志模块一切履行引擎都能够共用。
            • 引擎层是插件式的,现在首要包含,MyISAM,InnoDB,Memory等。
            • 查询句子的履行流程如下:权限校验(假如射中缓存)---》查询缓存---》剖析器---》优化器---》权限校验---》履行器---》引擎
            • 更新句子履行流程如下:剖析器----》权限校验----》履行器---》引擎---redo log(prepare 状况---》binlog---》redo log(commit状况)

            来历:http://t.cn/Ex1fQ2d


            查找微信号(ID:芋道源码),能够获得各种 Java 源码解析。

            而且,回复【书本】后,能够收取笔者引荐的各种 Java 从入门到架构的书本。

            来吧,骚年~

            请关注微信公众号
            微信二维码
            不容错过
            Powered By Z-BlogPHP