共计 3287 个字符,预计需要花费 9 分钟才能阅读完成。
前言
最近敌人小王正在找工作,而后有一个面试官问他知不知道 “查问 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 分为内存架构、磁盘架构?
❤ 关注 + 点赞 + 珍藏 + 评论 哟
如果本文对您有帮忙的话,请挥动下您爱发财的小手点下赞呀,您的反对就是我一直创作的能源,谢谢!
您能够 VX 搜寻【木子雷】公众号,保持高质量原创 java 技术文章,值得您关注!
参考资料
①、查问 sql 的执行过程及 MySQL 架构剖析
②、执行 SQL 查问语句时, 其底层到底经验了什么?