前言

最近敌人小王正在找工作,而后有一个面试官问他知不知道 “查问sql具体的执行流程”

小王说不晓得呀,而后面试官间接对小王说:小伙子 耗子尾汁(好自为之) ,怎么连这么简略的都不晓得呢?

小王听后脱口而出:哼!面试官你 不讲武德 ,不按套路出牌呀,你应该问问索引相干的常识呀,这个我倍分明。

在听完小王形容后,本人也在脑海中搜了搜这个知识点,可怜的是我的知识库里也没找到相干内容,而后就去面壁思过了,随后本文就诞生了。

留神 :本文次要以 MySql 为例;说到了MySql了,而后再唠叨下当初应用非常广泛的MySql的姊妹数据库 MariaDB

MariaDB 是个什么东东呢?

MySql被Oracle收买后,MySql的创始人放心MySql数据库倒退的将来(开发迟缓、关闭、可能会被闭源),于是创立了一个分支MariaDB,默认应用全新的Maria存储引擎,它是原来Mysql中的 MyISAM 存储引擎的升级版。

本文主线:

①、MySql的整体架构形容;

②、Server层各节点形容;

③、InnoDB存储引擎形容;

MySql架构形容

咱啥也先不说,先贴上一张摘抄自网上的大图:

下面这张图形容的清不清晰呢?不清晰,那别着急,咱再贴一张:

Server服务层形容:

通过下面的架构图能够得悉,Server层中次要由 连接器、查问缓存、解析器/分析器、优化器、执行器 几局部组成的,上面将次要形容下这几局部。

连接器

客户端想要对数据库进行操作时,前提是与数据库建设好连贯;而连接器就是用来负责跟客户端建设连贯、获取权限、维持和治理连贯的。

连贯形式:

MySQL既反对短连贯,也反对长连贯。短连贯就是操作结束后,马上close关掉。

长连贯能够放弃关上,缩小服务端创立和开释连贯的耗费,前面的程序拜访的时候还能够应用这个连贯。 个别咱们会在连接池中应用长连贯。

长连贯应用时的注意事项:

客户端与服务器建设长连贯,默认无效工夫是 8小时 ,超过8小时MySql服务器就会将连贯断开了,那么客户端再次申请的话,就会报 连贯已断开的问题

并且放弃长连贯会耗费内存。长时间不流动的连贯,MySQL服务器会断开。那这个8小时的超时工夫怎么查看呢?

-- 非交互式超时工夫,如 JDBC 程序show global variables like 'wait_timeout';  -- 交互式超时工夫,如数据库工具show global variables like' interactive_timeout'; 复制代码

执行后失去下图后果:默认都是28800秒,8小时 。

个别我的项目中应用的连接池中的连贯都是长连贯的;(例如:druid、c3p0、dbcp等)

举个例子,阐明下长连贯超时断开导致的理论问题:

某个敌人的公司有个管理系统,这个零碎应用的时Mysql,然而他最近遇到了一个问题:就是零碎明明前天是好用的,然而第二天去到公司后就打不开了,只有将零碎重启就好了,一时间不晓得什么起因,什么鬼嘛,苦恼?

最初通过查看日志才发现是连接池中的连贯都断开了,因为从前天到第二天下班这之间隔得工夫超过了8小时了。 唉,这么个小知识点导致好几天的困惑,切实不该呀,还是常识把握的不全面呀。

好了,当初也找到问题起因了,然而它该怎么解决呢?

长连贯超时断开的解决方案:

①、定期断开长连贯。应用一段时间,或者程序外面判断执行过一个占用内存的大查问后,断开连接,之后要查问再重连。

②、如果你用的是 MySQL 5.7 或更新版本,能够在每次执行一个比拟大的操作后,通过执行 mysql_reset_connection 来从新初始化连贯资源。这个过程不须要重连和从新做权限验证,然而会将连贯复原到刚刚创立完时的状态。

查问缓存

MySQL缓存是默认敞开的,也就是说不举荐应用缓存,为什么呢?

MySql为什么默认不开启缓存呢?

次要是因为它的应用场景限度的:

①、先说下缓存中数据存储格局:key(sql语句)-value(数据值);所以如果SQL语句(key)只有存在一点不同之处就会间接进行数据库查问了;

②、因为表中的数据不是变化无穷的,大多数是常常变动的,而当数据库中的数据变动了,那么相应的与此表相干的缓存数据就须要移除掉;

须要留神的是, MySQL 8.0 版本间接将查问缓存的整块性能删掉了,也就是说8.0开始彻底没有这个性能了。

分析器

分析器的工作次要是对要执行的SQL语句进行解析,最终失去形象语法书,而后再应用预处理器判断形象语法树中的表是否存在,如果存在的话,在接着判断select投影列字段是否在表中存在等。

词法剖析

词法剖析用于将SQL拆解为不可再分的原子符号,称为Token。并依据不同数据库方言所提供的字典,将其归类为关键字,表达式,字面量和操作符。

语法分析

语法分析就是依据词法剖析拆解进去的Token(原子符号)将SQL语句转换为形象语法树。上面就间接举例说明,看一个SQL它的形象语法书到底长神魔样:

SQL语句:

SELECT id, name FROM t_user WHERE status = 'ACTIVE' AND age > 18复制代码

而后下面的SQL语句通过词法剖析、语法分析后失去的形象语法书如下:

图片摘自:https://shardingsphere.apache...

留神,为了便于了解,形象语法树中的关键字的Token用绿色示意,变量的Token用红色示意,灰色示意须要进一步拆分。

预处理器

预处理是用来对生成的 形象语法树 进行语义校验,语义校验就是对查问的表、select投影列字段进行校验,判断表、字段是否存在等;

优化器

优化器的作用: 次要是将SQL通过词法解析/语法解析后失去的语法树,通过MySQL的数据字典和统计信息的内容,通过 一系列运算 ,从而得出一个 执行打算

在优化过程中,通过的一系列运算是什么呢?上面简略说下:

①、逻辑变换:例如SQL的where条件中存在 8>9,那逻辑转换就是将语法树中存在的这种常量表达式间接进行化简,化简为 false;除了化简还有常量表达式计算等。

②、代价优化:就是通过付出一些数据统计分析的代价,来失去这个SQL执行是否能够走索引,以及走哪些索引;除此之外,在多表关联查问中,确定最终表join的程序等;

在剖析是否走索引查问时,是通过进行 动态数据采样统计分析进去;只有是统计分析进去的,那就可能会存在剖析谬误的状况,所以在SQL执行不走索引时,也要思考到这方面的因素。

MySql执行打算怎么查看呢?

在执行的SQL语句前增加上 explain 关键字即可;

扩大: Oracle怎么查看执行打算? 参考此文章 Oracle通过执行打算查看查问语句是否应用索引

执行器

MySQL 通过分析器晓得了你要做什么,通过优化器晓得了该怎么做,于是就进入了执行器阶段,开始执行语句。 开始执行的时候,要先判断一下建设连贯的对象对这个表有没有执行操作的权限,如果没有,就会返回没有权限的谬误;如果有,就依照生成的执行打算进行执行。

通过文章最开始的架构图可知,执行器上面连贯的就是存储引擎了,执行器就是通过调用存储引擎提供的API接口进行调用操作数据的。

存储引擎形容

存储引擎是对底层物理数据执行实际操作的组件,为Server服务器层提供各种操作数据的 API。MySQL 反对插件式的存储引擎,包含 InnoDB 、MyISAM、Memory 等。个别状况下,MySQL默认应用的存储引擎是 InnoDB

InnoDB 存储引擎反对的性能总览

扩大

InnoDB存储引擎深刻学习,啥也不说了,先贴上其整体架构图:如下图所示,InnoDB存储引擎整体分为内存架构(Memory Structures)和磁盘架构(Disk Structures)。

如果想深刻学习,请参考此文章 你竟然还不晓得Mysql存储引擎InnoDB分为内存架构、磁盘架构? 《2020最新Java根底精讲视频教程和学习路线!》

原文链接:https://juejin.cn/post/689738...