引言
本文为社区首发签约文章,14天内制止转载,14天后未获授权制止转载,侵权必究!
MySQL
数据库从1995
年诞生至今,现已过去了二十多个年初了,到2022.04.26
日中止,MySQL8.0.29
正式发行了GA
版别,在此之前版别也产生了多次迭代,发行了大大小小N
多个版别,其间每个版别中都有各自的新特性,悉数版别的特性加起来,用一本书的篇幅也无法彻底论述清楚,因而本章首要会挑要点特性来讲,具体各版别的特性可参阅MySQL
官网的开发手册:
- 《MySQL官网-5.6版手册》
- 《MySQL官网-5.7版手册》
- 《MySQL官网-8.0版手册》
这儿首要讲一下5.6、5.7、8.0
这三个版别,由于这三个版别归于MySQL
里程碑式的发行版,其实除开这三个版别外,5.1
版别也是早期最主流的版别,但迄今中止基本上都并不必该版别了,因而不再对其做过多描绘。
一、MySQL5.6支撑的新技能
MySQL5.6
是Oracle
的得意之作,该版别是让MySQL
真实走向高功用数据库的里程碑版别,在此之前的MySQL
版别中,尽管功用也较为丰富,但功用相较于同期的Oracle
数据库而言,其实体现并欠安。直到Oracle
公司接手MySQL
后,首要就对其进行了雷厉风行的改善,从Oracle
中移植了许多特性过来,一起废弃一些原有的鸡肋功用,也优化了许多内部完结,终究打造出了MySQL5.6
这个版别。
但这儿关于
MySQL5.6
中不重要的特性不会罗列,要点解说一些较为重要的新特性。
1.1、支撑只读事务(Read-Only)
在此之前的版别中,MySQL
默许会为每个事务都分配事务ID
,悉数事务都天公地道,但在5.6
版别中开端支撑只读事务,MySQL
内部会有两个事务链表,一个是只读事务链表,一个是正常事务链表。
当一个事务中只要读操作时,
MySQL
并不会为这些事务分配ID
,默许悉数为0
(可是会分配查询ID
),然后将其标记为一个只读事务,并加入只读事务链表中,直到当这个事务中呈现改动数据的操作时,才会正式为其分配事务ID
,以及将其挪动到正常事务链表中。
这样做的优点在于:其他事务使用MVCC
机制读取数据时,生成的ReadView
读视图中的活跃事务链表会小许多许多,因而遍历的速度更快,一起也无需为其分配回滚段,然后进一步进步了MySQL
全体的查询功用。
1.2、InnoDB存储引擎增强
首要就说一下InnoDB
的核心:BufferPool
缓冲池相关的改善项,首要有两点:刷盘战略改善、缓冲池预热。
1.2.1、缓冲池刷盘战略优化
在之前的版别的InnoDB-BufferPool
缓冲池中,改动过的数据页会共用MySQL
后台的刷盘线程,也便是redo-log、undo-log、bin-log.....
一系列内存到磁盘的刷盘作业,都是选用同一批线程来完结。在MySQL5.6
版别中,BufferPool
引进了独立的刷盘线程,也就意味着缓冲池中改动过的数据页会由专门的线程来负责刷盘,这样能够进步缓冲池的刷盘功率,无需排队等待刷写。
一起
BufferPool
的刷盘线程,还支撑敞开多线程并发刷盘操作,这样在缓冲池较大的状况下,能够进一步进步刷盘的功率,然后让数据落盘的功率更快,从必定程度上也进步了数据的安全性,究竟内存中的数据随时都有几率丢掉,但落盘后基本上不是硬件损坏,都有或许康复过来。
1.2.2、BufferPool缓冲池预热
缓冲池预热是一种特别好的机制,在之前版别的内存缓冲池中,当MySQL
封闭时,本来内存中的热门数据都会被清空,重启后悉数的热门数据又需求经过时刻的沉积,然后才干留在内存中。但MySQL5.6
版别中,每次封闭MySQL
时都会将内存中的热门数据页保存到磁盘中,当重启时会直接从磁盘中载入之前的热门数据,避免了热门数据的从头“选拔”!
这样做的优点无疑是巨大的,举个比如就能够了解,如下:
现在整个村庄中选拔综合才干最强的男人,本来现已选拔了一批相对来说最优异的人出来,但由于村庄暂时呈现变故需求集体外出,所以本次选拔赛会被搁浅,当处理好变故后再次敞开选拔赛,又从头从头开端选拔,这明显非常影响功率。
而预热的含义是:呈现意外变故时,先将上次选拔赛中最优异的那批人,把对应的姓名保存在一个名单中,处理完变故后,只需求找到这个名单,把名单上的人喊过来持续选拔即可,这样做明显将功率进步了N
倍。
1.3、新增Performance_Schema库监控大局资源
假如对MySQL
比较熟悉的小伙伴应该清楚,在之前的版别中存在一个名为information_schema
的库,其间会记载一些MySQL
工作期间需求用到的表,比方视图办理、存储进程与函数的办理、暂时表的办理、会话的办理、触发器的办理、表分区的办理……,这些内容的信息都会被存储到information_schema
库中。
而在MySQL5.6
中,官方又加入了一个新的自带库:performance_schema
,这儿面会记载:数据库全体的监控信息,比方事务监控信息、最近履行的SQL
信息、最近衔接的客户端信息、数据库各空间的运用信息……,依据这个库能够在线上构建出一个完善的MySQL
监控体系:
-
Statements/execution stages
:MySQL
计算的一些耗费资源较高的SQL
句子。 -
Table and Index I/O
:MySQL
计算的那些表和索引会导致I/O
负载过高。 -
Table Locks
:MySQL
计算的表中数据的锁资源竞争信息。 -
Users/Hosts/Accounts
:耗费资源最多的客户端、IP
机器、用户。 -
Network I/O
:MySQL
计算的一些网络相关的资源状况。 .......
1.4、索引下推机制(Index Condition Pushdown)
Index Condition Pushdown
索引下推简称ICP
,它是MySQL5.6
版别以后引进的一种优化机制,以下述用户表为例,这张表上依据姓名、性别、暗码字段树立了一个联合索引,此刻先来看看下面的状况:
select * from `zz_users`;
+---------+-----------+----------+----------+---------------------+
| user_id | user_name | user_sex | password | register_time |
+---------+-----------+----------+----------+---------------------+
| 1 | 熊猫 | 女 | 6666 | 2022-08-14 15:22:01 |
| 2 | 竹子 | 男 | 1234 | 2022-09-14 16:17:44 |
| 3 | 子竹 | 男 | 4321 | 2022-09-16 07:42:21 |
| 4 | 猫熊 | 女 | 8888 | 2022-09-17 23:48:29 |
+---------+-----------+----------+----------+---------------------+
INSERT INTO `zz_users` VALUES(5,"竹竹","女","8888","2022-09-20 22:17:21");
SELECT * FROM `zz_users` WHERE `user_name` LIKE "竹%" AND `user_sex`="男";
首要为了愈加直观的讲清楚索引下推,因而先再向用户表中添加一条数据。然后再来看看后面的查询SQL
,这条SQL
会运用联合索引吗?答案是会的,但只能部分运用,由于联合索引的每个节点信息大致如下:
{
["熊猫","女","6666"] : 1,
["竹子","男","1234"] : 2,
["子竹","男","4321"] : 3,
["猫熊","男","4321"] : 4,
["竹竹","女","8888"] : 5
}
由于前面运用的是含糊查询,但%
在结尾,因而能够运用竹
这个字作为条件在联合索引中查询,整个查询进程如下:
- ①使用联合索引中的
user_name
字段找出「竹子、竹竹」两个索引节点。 - ②回来索引节点存储的值「
2、5
」给Server
层,然后去逐个做回表扫描。 - ③在
Server
层中依据user_sex="男"
这个条件逐条判别,终究挑选到「竹子」这条数据。
有人或许会疑问,为什么user_sex="男"
这个条件不在联合索引中处理呢?由于前面是含糊查询,所以拼接起来是这样的:竹x男
,由于这个x
是不知道的,因而无法依据最左前缀准则去匹配数据,终究这儿只能运用联合索引中user_name
字段的一部分,后续的user_sex="男"
还需求回到Server
层处理。
那什么又叫做索引下推呢?也便是将
Server
层挑选数据的作业,下推到引擎层处理。
以前面的事例来解说,MySQL5.6
加入索引下推机制后,其履行进程是什么样子的呢?
- ①使用联合索引中的
user_name
字段找出「竹子、竹竹」两个索引节点。 - ②依据
user_sex="男"
这个条件在索引节点中逐个判别,然后得到「竹子」这个节点。 - ③终究将「竹子」这个节点对应的「
2
」回来给Server
层,然后聚簇索引中回表拿数据。
相较于没有索引下推之前,本来需求做「2、5
」两次回表查询,但在具有索引下推之后,仅需做「2
」一次回表查询。
索引下推在
MySQL5.6
版别之后是默许敞开的,能够经过指令set optimizer_switch='index_condition_pushdown=off|on';
指令来手动办理。
1.5、MRR(Multi-Range Read)机制
Multi-Range Read
简称为MRR
机制,这也是和索引下推一同在MySQL5.6
版别中引进的功用优化办法,那什么叫做MRR
优化呢?
一般来说,在实践事务中我们应当尽量经过索引掩盖的特性,削减回表操作以下降
IO
次数,但在许多时候往往又不得不做回表才干查询到数据,但回表明显会导致产生许多磁盘IO
,一起更严峻的一点是:还会产生许多的离散IO
,下面举个比如来了解。
SELECT * FROM `zz_student_score` WHERE `score` BETWEEN 0 AND 59;
上述这条SQL
所做的作业很简略,便是在学生成果表中查询悉数成果未及格的学生信息,假定成果字段上存在一个一般索引,那考虑一下,这条SQL
的履行流程是什么样的呢?
- ①先在成果字段的索引上找到
0
分的节点,然后拿着ID
去回表得到成果零分的学生信息。 - ②再次回到成果索引,持续找到悉数
1
分的节点,持续回表得到1
分的学生信息。 - ③再次回到成果索引,持续找到悉数
2
分的节点…… - ④循环往复,不断重复这个进程,直到将
0~59
分的悉数学生信息悉数拿到中止。
那此刻假定此刻成果0~5
分的表数据,位于磁盘空间的page_01
页上,而成果为5~10
分的数据,位于磁盘空间的page_02
页上,成果为10~15
分的数据,又位于磁盘空间的page_01
页上。此刻回表查询时就会导致在page_01、page_02
两页空间上来回切换,但0~5、10~15
分的数据彻底能够兼并,然后读一次page_01
就能够了,既能削减IO
次数,一起还避免了离散IO
。
而
MRR
机制就首要是处理这个问题的,针关于辅助索引的回表查询,削减离散IO
,而且将随机IO
转换为次序IO
,然后进步查询功率。
那MRR
机制具体是怎样做的呢?MRR
机制中,关于辅助索引中查询出的ID
,会将其放到缓冲区的read_rnd_buffer
中,然后等悉数的索引检索作业完结后,或许缓冲区中的数据到达read_rnd_buffer_size
大小时,此刻MySQL
会对缓冲区中的数据排序,然后得到一个有序的ID
调集:rest_sort
,终究再依据次序IO
去聚簇/主键索引中回表查询数据。
SET @@optimizer_switch='mrr=on|off,mrr_cost_based=on|off';
能够经过上述这条指令敞开或封闭MRR
机制,MySQL5.6
及以后的版别是默许敞开的。
1.6、主从数据同步的仿制改善
随着互联网时代浪潮的兴起,体系中的并发量、数据量日益增长,传统的单库在有些状况下就有些乏力,开端只能经过不断晋级硬件配置的手段来进步功用。可单机的功用无论怎么晋级硬件,总有到达瓶颈的一天,因而散布式的概念开端进入我们眼中,而MySQL5.6
中也针关于多节点布置的状况,其数据同步问题做了大幅度优化。
在
MySQL5.6
中,针关于主从数据同步的问题,首要引进了GTID
仿制、无损仿制(增强半同步仿制)、延时仿制、并行仿制这四种技能,但由于现在《MySQL专栏》还未开端发布“MySQL
高可用”相关的文章,因而这些内容会在后续的《主从仿制篇》论述。
1.7、MySQL5.6中的其他特性
前面介绍的几点,归于比较重要的一些知识,但除此之外,5.6
版别中还存在许多特性与优化项,如:
- 索引增强:全文索引支撑
InnoDB
与亚洲语种分词、支撑空间索引等。 - 表分区增强:单表分区数量最大可创立
8192
个、分区锁功用进步、支撑cloumns
分区类型。 - 增强日期类型:
time、datetime、timestamp
精度进步到微秒级,datetime
容量缩减到5
字节。 - 日志增强:
Redo-log
文件大小约束由4G→512G
、Undo-log
文件可独立指定方位存储。 - 支撑在线
DDL(Online DDL)
、对limit
句子做了优化……
除开上述外,还有许多许多与之前不同的改动,官方声称在5.6
中修复了1667
个Bug
,因而想要更为全面的了解,可阅读《MySQL官网-5.6版手册》。
二、MySQL5.7引进的新特性
相较于长辈5.6
、后辈8.0
而言,MySQL5.7
版别就显的中规中矩,其间没有产生太多的改动,MySQL5.7
更倾向于5.6
的稳定版,究竟5.6
版别中步子迈的太大,许多方面的技能都需求依据市场反馈做纤细调整,因而成功的为MySQL5.7
做好了衬托,一般的项目假如不选用MySQL8.0
,基本上都会挑选MySQL5.7
而不是5.6
。
但
MySQL5.7
中也存在几个能令人眼前一亮的优化项,接着就要点聊一聊这些要点~
2.1、引进同享排他锁
在MySQL5.7
之前的版别中,数据库中仅存在两种类型的锁,即同享锁与排他锁,可是在MySQL5.7.2
版别中引进了一种新的锁,被称之为(SX)
同享排他锁,这种锁是同享锁与排他锁的杂交类型,至于为何引进这种锁呢?聊它之前需求先了解SMO
问题:
在
SQL
履行期间一旦更新操作触发B+Tree
叶子节点割裂,那么就会对整棵B+Tree
加排它锁,这不但堵塞了后续这张表上的悉数的更新操作,一起也阻挠了悉数试图在B+Tree
上的读操作,也便是会导致悉数的读写操作都被堵塞,其影响巨大。因而,这种大粒度的排它锁成为了InnoDB
支撑高并发拜访的首要瓶颈,而这也是MySQL 5.7
版别中引进SX
锁要处理的问题。
那想一下该怎么处理这个问题呢?最简略的方法便是减小SMO
问题产生时,确定的B+Tree
粒度,当产生SMO
问题时,就只确定B+Tree
的某个分支,而并不是确定整颗B+
树,然后做到不影响其他分支上的读写操作。
那
MySQL5.7
中引进同享排他锁后,究竟是怎么完结的这点呢?先聊聊SX
锁的特性,它不会堵塞S
锁,可是会堵塞X、SX
锁,下面打开来说说。
在聊之前得搞清楚SQL
履行时的几个概念:
- 读取操作:依据
B+Tree
去读取某条或多条行记载。 - 达观写入:不会改动
B+Tree
的索引键,仅会更改索引值,比方主键索引树中不修正主键字段,只修正其他字段的数据,不会引起节点割裂。 - 失望写入:会改动
B+Tree
的结构,也便是会造成节点割裂,比方无序刺进、修正索引键的字段值。
在MySQL5.6
版别中,一旦有操作导致了树结构产生改变,就会对整棵树加上排他锁,堵塞悉数的读写操作,而MySQL5.7
版别中,为了处理该问题,关于不同的SQL
履行,流程就做了调整。
2.1.1、MySQL5.7中读操作的履行流程
- ①读取数据之前首要会对
B+Tree
加一个同享锁。 - ②在依据树检索数据的进程中,关于悉数走过的叶节点会加一个同享锁。
- ③找到需求读取的方针叶子节点后,先加一个同享锁,开释进程②上加的悉数同享锁。
- ④读取终究的方针叶子节点中的数据,读取完结后开释对应叶子节点上的同享锁。
2.1.2、MySQL5.7中达观写入的履行流程
- ①达观写入之前首要会对
B+Tree
加一个同享锁。 - ②在依据树检索修正方位的进程中,关于悉数走过的叶节点会加一个同享锁。
- ③找到需求写入数据的方针叶子节点后,先加一个排他锁,开释进程②上加的悉数同享锁。
- ④修正方针叶子节点中的数据后,开释对应叶子节点上的排他锁。
2.1.3、MySQL5.7中失望写入的履行流程
- ①失望更新之前首要会对
B+Tree
加一个同享排他锁。 - ②由于①上现已加了
SX
锁,因而当时事务履行进程中会堵塞其他测验更改树结构的事务。 - ③遍历查找需求写入数据的方针叶子节点,找到后对其分支加上排他锁,开释①中加的
SX
锁。 - ④履行
SMO
操作,也便是履行失望写入操作,完结后开释进程③中在分支上加的排他锁。
假如需求修正多个数据时,会在遍历查找的进程中,记载下悉数要修正的方针节点。
2.1.4、MySQL5.7中并发事务抵触剖析
调查上述讲到的三种履行状况,关于读操作、达观写入操作而言,并不会加SX
锁,同享排他锁仅针关于失望写入操作会加,由于读操作、达观写入履行前对整颗树加的是S
锁,因而失望写入时加的SX
锁并不会堵塞达观写入和读操作,但当另一个事务测验履行SMO
操作改动树结构时,也需求先对树加上一个SX
锁,这时两个失望写入的并发事务就会呈现抵触,新来的事务会被堵塞。
可是要注意:当第一个事务寻找到要修正的节点后,会对其分支加上
X
锁,紧接着会开释B+Tree
上的SX
锁,这时别的一个履行SMO
操作的事务就能获取SX
锁啦!
其实从上述中或许得知一点:MySQL5.7
版别引进同享排他锁之后,处理了5.6
版别产生SMO
操作时堵塞悉数读写操作的问题,这样能够在必定程度上进步了InnoDB
表的并发功用。
最后要注意:尽管一个履行失望写入的事务,找到了要更新/刺进数据的节点后会开释
SX
锁,可是会对其上级的叶节点(叶分支)加上排他锁,因而正在产生SMO
操作的叶分支,仍旧是会堵塞悉数的读写行为!
上面这句话啥意思呢?也便是当一个要读取的数据,位于正在履行SMO
操作的叶分支中时,仍旧会被堵塞。
2.2、MySQL开端支撑json格局
随着非结构化数据的存储需求持续增长,各类非联系型数据库应运而生,例如大名鼎鼎的MongoDB
,各大联系型数据库为了防止市场占用率流失,也开端补偿关于这块的支撑,因而在MySQL5.7.8
版别中也支撑了json
数据类型,而且为其供给了一系列操作的API
。
尽管说
MySQL
也支撑了json
格局存储,但明显是亡羊补牢,为时已晚,天然无法抢过MongoDB
的市场占用率,从功用和存储容量来说,MySQL
也无法竞争过MongoDB
,但相较于其他非结构化数据库,MySQL
存储json
数据有两大优势:①关于json
数据的API
操作支撑事务。②支撑为一个表字段设置json
格局,也就意味着MySQL
中能够将结构化数据和非结构化数据共同存储。
2.3、MySQL5.7中的其他特性
除开上述两点值得打开叙说的特性外,其他的基本上是一些纤细改变,因而就不对其进行打开叙述啦,这儿稍微罗列一下MySQL5.7
版别中,其他的特性支撑,如下:
- 暂时表优化,暂时表的写操作不记载
redo-log
、不为其生成缓冲数据页,减小资源占用。 - 多接点布置时,数据同步仿制再次优化,支撑多主/源仿制、以及真实意义上的并行仿制等。
- 引进了虚拟列的完结,类似于
Oracle
数据库中的函数索引。 - 移除了默许的
test
数据库,以及默许不会创立匿名用户,引进暗码过期战略。 - 触发器增强,表上同一种事件、同一机遇的触发器可创立多个,之前则只能答应创立一个。
- 推出了新的
mysqlpump
工具,用于数据的逻辑备份、引进了新的客户端工具mysqlsh
等。 - 支撑经过
max_execution_time
约束一条SQL
的履行超时时刻、支撑innodb_deadlock_detect
死锁检测。 -
GIS
空间数据类型增强,运用Boost.Geometry
代替原有的GIS
算法,InnoDB
支撑空间索引。 .......
除此之外其实也仍旧存在其他许多细节方面的新特性支撑和优化项,具体可参阅《MySQL官网-5.7版手册》。
三、MySQL8.0产生的大改动
在MySQL8.0
发行前,基本上悉数运用MySQL
数据库的企业/个人项目,基本上都归于MySQL5.6/5.7
的钉子户,基本上不会再挑选除此之外的发行版,但随着MySQL8.0
的发行,打破了这个局面,官方声称经压测后,8.0
比5.7
功用足足进步了200%
,这无疑关于MySQL
的忠诚用户而言,明显是一个非常巨大的诱惑。
由于依照理论来说,只要你将项目中的
MySQL
,从原有的MySQL5.7
版别晋级到MySQL8.0
版别,从数据库的功用上来说,无需你手动做任何优化,就能够让功用翻倍。
不过的确在MySQL8.0
版别中,再次推出了非常多重要的新特性,也推出了许多关于功用的优化项,因而接下来打开聊聊最新的MySQL8.0
系版别。
3.1、移除查询缓存(Query Cache)
Query Cahce
查询缓存的规划初衷很好,也便是使用热门勘探技能,关于一些频频履行的查询SQL
,直接将成果缓存在内存中,之后再次来查询相同数据时,就无需走磁盘,而是直接从查询缓存中获取数据并回来。
听起来好像还不错呀,如同的确能带来不小的功用进步呢?但实则很鸡肋,为啥?看个比如。
select * from zz_users where user_id=1;
select * from zz_users where user_id = 1;
比方上述这两条SQL
句子,在我们看来是不是相同的?的确,都是在查询ID=1
的用户数据,但奇葩的工作呈现了,MySQL
的查询缓存会把它当做两条不同的SQL
,也便是假如上面的第一条SQL
,其查询成果被放入到了缓存中,第二条SQL
仍旧无法射中这个缓存,会持续走表查询的方法获取数据,Why
?
由于
MySQL
查询缓存是以SQL
的哈希值来作为Key
的,上面两条SQL
尽管相同,可是后面的查询条件有纤细差别:user_id=1、user_id = 1
,也便是一条SQL
有空格,一条没有。
由于这一点点纤细差异,会导致两条SQL
计算出的哈希值彻底不同,因而无法射中缓存,是不是很鸡肋?还有多种状况:user_id =1、user_id= 1
,空格处于的前后方位不同,也会导致缓存失效。
也正是由于方方面面的原因,所以查询缓存在
MySQL8.0
中被彻底舍弃了,即移除掉了查询缓存区,各方面原因如下:
- ①缓存射中率低:简直大部分
SQL
都无法从查询缓存中取得数据。 - ②占用内存高:将许多查询成果放入到内存中,会占用至少几百
MB
的内存。 - ③添加查询进程:查询表之前会先查一次缓存,查询后会将成果放入缓存,额定多几步开支。
- ④缓存保护本钱不小,需求
LRU
算法筛选缓存,一起每次更新、刺进、删除数据时,都要清空缓存中对应的数据。 - ⑤查询缓存是专门为
MyISAM
引擎规划的,而InnoDB
构建的缓冲区彻底具有查询缓存的效果。
由于上述一系列原因,再加上项目中一般都会运用Redis
先做事务缓存,因而能来到MySQL
的查询句子,简直都是要从表中读数据的,所以查询缓存的位置就显得愈加突兀,所以在8.0
版别中就直接去掉了,究竟弊大于利,带来的收益达不到规划时的预期。
3.2、锁机制优化
在MySQL8.0
中的锁机制首要呈现了两点优化,一方面临获取同享锁的写法进行了优化,如下:
-- MySQL8.0之前的版别
SELECT ... LOCK IN SHARE MODE;
-- MySQL8.0及后续的版别
SELECT ... FOR SHARE;
第二方面则支撑非堵塞式获取锁机制,能够在获取锁的写法上加上NOWAIT、SKIP LOCKED
关键字,这样在未获取到锁时不会堵塞等待,运用SKIP LOCKED
未获取到锁时会直接回来空,运用NOWAIT
会直接回来并向客户端回来异常。用法如下:
select ... for update nowait;
select ... for update skip locked;
3.3、在线修正的体系参数支撑耐久化
在之前的版别中,经过set、set global
的方法修正某个体系变量时,这种方法设置的参数值都是一次性的,也便是修正过的参数并不会被同步到本地,当MySQL
重启时,这些调整过的参数又会回归默许值,假如想要让调整过的参数收效,就有必要要手动中止MySQL
,然后去修正my.ini/my.conf
文件,修正完结后再重启数据库服务,这时才干让参数永久收效。
这种方法无疑是非常痛苦的,尤其是在做数据库线上调优时,修正参数后重启又会失效,有时重启忘记再次调整参数,终究导致数据库服务呈现问题,这种体验令人很糟心。
而在MySQL8.0
中则彻底优化了这个问题,推出了在线修正参数后,支撑耐久化到本地文件的机制,也便是经过SET PERSIST
指令来完结,如下:
-- 调整事务的阻隔等级(针关于当时衔接有用)
set transaction isolation level read uncommitted;
-- 调整事务的阻隔等级(针关于大局有用,重启后会丢掉)
set global tx_isolation = "read-committed";
-- 调整事务的阻隔等级(针关于大局有用,而且会耐久化到本地,重启后不会丢掉)
set persist global.tx_isolation = "repeatable-read";
经过set persist
指令耐久化的参数,能够经过下述指令来查看:
select * from performance_schema.persisted_variables;
这条指令的本质其实是:依据MySQL
自带的performance_schema
监控库查询耐久化过的参数。
其实参数耐久化的原理也非常简略,当履行
set persist
指令时,会将改动过的参数写入到本地的mysqld-auto.cnf
文件中,MySQL
每次启动时都会读取这个文件中的值,假如该文件中存在参数,则会直接将其加载,然后完结了一次修正,永久有用。
但当你想要参数不再耐久化到本地时,能够挑选删除装置目录下的mysqld-auto.cnf
文件,或履行reset persist
指令来清除,但这两种方法都只对下次重启时收效,究竟本次参数现已被载入内存了,所以只能经过再次手动修正的方法康复。
3.4、增强多表衔接查询
在之前的MySQL
版别中,仅支撑穿插衔接、内衔接、左外衔接、右外衔接四种衔接类型,这四种衔接都会选用默许的衔接算法,而在8.0
版别中供给了哈希衔接、反衔接两种衔接优化的支撑。
3.1.1、哈希衔接(Hash Join)
所谓的哈希衔接其实并非一种新的连表方法,而是一种连表查询的算法,在联系型数据库中多表连查一般有三种算法:Hash-Join
哈希散列衔接、Sort-Merge-Join
排序兼并衔接、Nest-Loop-Join
嵌套循环衔接,这三种连表算法在Oracle
数据库中都支撑,但MySQL
之前的版别中,悉数的连表方法都仅支撑Nest-Loop-Join
嵌套循环衔接,关于这点在《SQL优化篇-以小驱大》中聊到过。
而到了
MySQL8.0.18
版别发布后,MySQL
对内衔接的方法支撑了哈希衔接算法,那究竟啥叫哈希衔接算法呢?和之前传统的循环衔接算法又有啥差异呢?接下来一起打开聊一聊。
哈希衔接算法和循环衔接算法的差异
先来看看传统的循环衔接算法的连表查询进程是怎样样的呢?如下:
在循环衔接算法中,会首要挑选一张小表作为驱动表,然后顺次将驱动表中每一条数据作为条件,去被驱动表中做遍历,终究得到契合衔接条件的悉数数据,也便是会形成一个下述的伪逻辑:
for(数据 x : 驱动表){
for(数据 y : 被驱动表){
if (x == y){
// 假如契合衔接条件,则记载到衔接查询的成果会集.....
}
}
}
这种循环衔接的算法中,明显会造成巨大的开支,由于驱动表每条数据都需求和被驱动表的完好数据做一次遍历。也正是为了处理这个问题,由于MySQL8.0
中引进了哈希衔接算法,进程如下:
在哈希衔接算法中会分为两个阶段:
- 构建阶段:挑选一张小表作为构建表,接着会依据衔接字段做哈希处理,生成哈希值放入内存中构建出一张哈希表。
- 勘探阶段:遍历大表的每一行数据,然后对衔接字段做哈希处理,经过生成的哈希值与内存哈希表做比较,契合条件则放入成果会集。
比照之前的循环衔接算法,这种哈希衔接算法带来的功用进步直线进步N
倍,由于在循环衔接算法中,需求遍历count(驱动表)
次,即驱动表中有多少条数据就要遍历多少次。而在这种算法中,只需求将大表遍历一次,伪逻辑代码如下:
// 构建阶段:将小表的每行数据,依据哈希值放入内存哈希表中
Map hashTable = new HashMap();
for(数据 x : 构建表){
hashTable.put(x);
}
// 勘探阶段:遍历大表的每行数据与内存哈希表做衔接匹配
for(数据 y : 勘探表){
if (hashTable.get(y) != null){
// 假如哈希处理后能够在内存哈希表中存在,
// 则表明这条数据契合衔接条件,则记载到衔接查询的成果会集.....
}
}
哈希衔接比照循环衔接算法而言,首要在两方面能够得到功用进步:
- ①哈希衔接算法中,只需求将大表遍历一次,但循环衔接算法需求遍历
N
次。 - ②哈希衔接勘探阶段,做衔接判别时只需求先对数据做一次哈希处理,然后在内存中查找即可,复杂度仅为
O(1)
,但循环衔接算法的复杂度为O(n)
。
哈希衔接算法的丧命问题
但尽管哈希衔接算法能够带来杰出的功用进步,但也存在一个丧命问题,便是内存中join_buffer_size
的容量无法彻底载入构建表的哈希数据时怎样办呢?这儿就有两种处理方案:
- ①分批处理,将构建表的数据拆分为几部分,每次载入一部分到内存,但这样会导致大表的遍历次数,随着分批次数变大而增多。
- ②使用磁盘完结,也便是首要将构建表的悉数数据做哈希处理,放不下时将一部分处理好的哈希数据放入磁盘,在勘探阶段遍历大表时,每次对大表数据生成哈希值后,做判别时从磁盘顺次读取处理好的哈希值做判别。
而MySQL
中挑选的是第二种,也便是当内存无法彻底放下构建表的哈希数据时,会选用磁盘+内存混合的模式履行哈希衔接。
MySQL什么状况下会选用哈希衔接?
首要并不是多表衔接的状况下都会运用哈希衔接算法,该算法有几个硬性约束:
- ①现在哈希衔接算法仅支撑内衔接的多表连查方法。
- ②哈希衔接算法有必要要求存在等值衔接条件,即
a.id=b.id
才行,a.id>b.id
是不可的。 - ③假如衔接字段能够走索引查询的状况下,默许仍旧会选用循环衔接算法。
第二点的原因在于:哈希衔接算法生成的哈希值是无序的,所以有必要要用等值衔接才行。
第三点的原因在于:衔接查询时走索引的功率并不低,哈希衔接需求生成哈希表,因而需求时刻,因而在能够走索引连表的状况下,哈希衔接算法的功率反而比不上循环衔接。
也便是说,当连表时存在等值衔接条件,而且未射中索引的状况下,
MySQL
默许会选用哈希衔接算法来完结连表查询,不过还有一种状况也会运用,便是笛卡尔积状况,即不指定衔接条件的状况下也会运用哈希衔接,此刻MySQL
会直接对整条数据生成哈希表。
关于哈希衔接算法,MySQL
是默许敞开的,我们可经过set optimizer_switch="hash_join=off";
的方法来手动操控开关。
3.1.2、反衔接(Anti Join)
反衔接是MySQL8.0
关于一些反范围查询操作的优化,首要针关于下述几种状况会做优化:
NOT IN (SELECT … FROM …)
NOT EXISTS (SELECT … FROM …)
IN (SELECT … FROM …) IS NOT TRUE
EXISTS (SELECT … FROM …) IS NOT TRUE
IN (SELECT … FROM …) IS FALSE
EXISTS (SELECT … FROM …) IS FALSE
在MySQL
早些版别中,运用NOT EXISTS、NOT IN、IS NOT...
这类操作时有或许会导致索引失效,而且也会让查询功率变低,因而MySQL8.0
版别中会对上述几类句子进行优化,当你的SQL
句子运用了上述语法检索数据时,在MySQL
内部会将其转变为反衔接类型的查询句子。
也便是会将右边的子查询成果集,变为一张物理暂时表,然后依据条件字段做衔接查询,官方声称在某些场景下,能够让上述几类句子的查询功用进步
20%
,但关于这块我没做深入研讨,因而就不打开叙述啦。
3.5、增强索引机制
在8.0
中官方再一次对索引机制动刀,首要对联合索引供给了一种跳动扫描机制的支撑,也就意味着运用联合索引时,就算未遵循最左前缀匹配准则,也能够运用联合索引来检索数据。除此之外,还有别的三种新的索引特性:躲藏索引、降序索引以及函数索引。
3.5.1、索引跳动式扫描机制(Index Skip Scan)
在之前讲《索引运用篇》时,我们初度提到了最左前缀匹配准则,也便是SQL
的查询条件中有必要要包括联合索引的第一个字段,这样才干射中联合索引查询,但实践上这条规则也并不是100%
遵循的。由于在MySQL8.0
版别中加入了一个新的优化机制,也便是索引跳动式扫描,这种机制使得我们即便查询条件中,没有运用联合索引的第一个字段,也仍旧能够运用联合索引,看起来就像跳过了联合索引中的第一个字段相同,这也是跳动扫描的称号由来。
但跳动扫描究竟是怎样完结的呢?上个栗子快速了解一下。
比方此刻经过(A、B、C)
三个列树立了一个联合索引,此刻有如下一条SQL
:
SELECT * FROM `tb_xx` WHERE B = `xxx` AND C = `xxx`;
按理来说,这条SQL
既不契合最左前缀准则,也不具有运用索引掩盖的条件,因而肯定是不会走联合索引查询的,但考虑一个问题,这条SQL
中都现已运用了联合索引中的两个字段,成果还不能运用索引,这好像有点亏啊对不?因而MySQL8.x
推出了跳动扫描机制,但跳动扫描并不是真实的“跳过了”第一个字段,而是优化器为你重构了SQL
,比方上述这条SQL
则会重构成如下状况:
SELECT * FROM `tb_xx` WHERE B = `xxx` AND C = `xxx`
UNION ALL
SELECT * FROM `tb_xx` WHERE B = `xxx` AND C = `xxx` AND A = "yyy"
......
SELECT * FROM `tb_xx` WHERE B = `xxx` AND C = `xxx` AND A = "zzz";
其实也便是MySQL
优化器会自动对联合索引中的第一个字段的值去重,然后依据去重后的值悉数拼接起来查一遍,一句话来概述便是:尽管你没用第一个字段,但我给你加上去,今天这个联合索引你就得用,不必也得给我用。
当然,假如熟悉
Oracle
数据库的小伙伴应该知道,跳动扫描机制在Oracle
中早就有了,但为什么MySQL8.0
版别才推出这个机制呢?还记得我们在《MySQL架构篇》中的闲谈嘛?MySQL
几经转手后,终究归到了Oracle
旗下,因而跳动扫描机制仅是Oracle
公司:从Oracle
搬到了“自己的MySQL
”上罢了。
可是跳动扫描机制也有许多约束,比方多表联查时无法触发、SQL
条件中有分组操作也无法触发、SQL
中用了DISTINCT
去重也无法触发…..,总归有许多约束条件,具体的能够参阅《MySQL官网8.0-跳动扫描》。
其实这个跳动性扫描机制,只要在唯一性较差的状况下,才干发挥出不错的效果,假如你联合索引的第一个字段,是一个值具有唯一性的字段,那去重一次再拼接,简直就等价于走一次全表。
关于索引跳动扫描机制,能够经过set @@optimizer_switch = 'skip_scan=off|on';
指令来挑选敞开或封闭跳动式扫描机制。
3.5.2、躲藏索引
躲藏索引并不是一种新的索引类型,而是一种对索引的骚操作,能够了解为对每个索引新增了一个开关按键,首要用于测验环境和灰度场景,在MySQL8.0
版别中,能够经过INVISIBLE、VISIBLE
来操控索引的开关:
- 当对一个索引运用
INVISIBLE
后,会封闭这个索引,优化器在履行SQL
时无法发现和运用它。 - 当对一个索引运用
VISIBLE
后,会将索引从躲藏状况康复到正常状况。
所谓的躲藏索引,便是指将一个现已创立的索引“藏起来”,被藏起来的索引是无法被优化器勘探到的,因而履行SQL
句子时,就算句子中显式运用了索引字段,优化器也不会挑选走这条索引。
这个特性首要是针关于调优、测验场景而研制的,假如躲藏一个索引后,在压测场景下不会对事务产生影响,假如经过重复测验后仍旧不影响
SQL
功用,那这条索引则能够被判定为无用索引,能够将其删除,躲藏索引的用法如下:
-- 躲藏某张表上已存在的一个索引
alter table 表名 alter index 索引名 invisible;
-- 康复某张表上已存在的一个索引
alter table 表名 alter index 索引名 visible;
3.5.3、降序索引
Descending index
降序索引是一种索引的特性,不知我们是否还记得之前界说索引的句子呢,如下:
ALTER TABLE tableName ADD INDEX indexName(columnName(length) [ASC|DESC]);
在创立索引时,能够经过ASC、DESC
来界说一个索引是按升序仍是降序存储索引键,但本质上这种语法,在MySQL8.0
之前,就算你手动写明了DESC
降序,在创立时仍旧会默许忽略,也便是本质上仍是按升序存储索引键的,当你要对某个倒序索引的字段做倒序时,仍旧会产生filesort
排序的动作。
到了
MySQL8.0
官方正式支撑降序索引,也便是当对一个字段树立降序索引后,做降序查询时不需求再次排序,可直接依据索引进行取值。
下面来依据MySQL5.1、MySQL8.0
举个简略的比如感受一下:
-- 分别在 MySQL5.1、MySQL8.0 中创立一张 zz_table 表
create table zz_table (
id1 int,
id2 int,
index idx1 (id1 ASC, id2 ASC),
index idx2 (id1 ASC, id2 DESC),
index idx3 (id1 DESC, id2 ASC),
index idx4 (id1 DESC, id2 DESC)
);
insert into zz_table values(1,2);
上述创立了一张索引的测验表zz_table
,其间关于两个字段树立四个索引:全升序、全降序、前降后升、前升后降,然后随便刺进了一条数据,接着来看看SQL
履行状况:
-- MySQL5.1版别中的测验
explain select * from zz_table order by id1 asc, id2 desc;
+----+-------------+----------+------+-----------------------------+
| id | select_type | table | .... | Extra |
+----+-------------+----------+------+-----------------------------+
| 1 | SIMPLE | zz_table | .... | Using index; Using filesort |
+----+-------------+----------+------+-----------------------------+
-- MySQL8.0版别中的测验
explain select * from zz_table order by id1 asc, id2 desc;
+----+-------------+----------+------------+-------+----------------------------------+
| id | select_type | table | partitions | ..... | Extra |
+----+-------------+----------+------------+-------+----------------------------------+
| 1 | SIMPLE | zz_table | NULL | ..... | Backward index scan; Using index |
+----+-------------+----------+------------+-------+----------------------------------+
要点调查最后一个Extra
字段,在MySQL8.0
之前的版别中,尽管对id2
树立了倒序索引,但实践做倒序查询时仍旧会产生Using filesort
排序动作,而MySQL8.0
中则直接是Backward index scan
反向索引扫描,并未触发排序动作。
3.5.4、函数索引
还记得在聊MySQL5.7
版别时,最后贴出的其他特性嘛?其间就有一条是引进了躲藏列,完结了类似于Oracle
中的函数索引,但其实功用并不健全,而在MySQL8.0
中真实的支撑了函数索引,也便是依据函数去创立索引,如下:
alter table 表名 add index 索引名(函数(列名));
-- 比方:创立一个将字段值悉数转为大写后的索引
alter table t1 add index fuc_upper(upper(c1));
依据某个字段创立一个函数索引后,之后依据该字段运用函数作为查询条件时,仍旧能够走索引,如下:
select * from t1 where upper(c1) = 'ABC';
上述这条SQL
句子,依照之前《索引运用篇-索引字段运用函数导致失效》中聊到的理论,理论上这条句子由于在=
前面运用了函数,明显会导致索引失效,但在MySQL8.0
中可创立函数索引,能够支撑条件查询时,在=
号之前运用函数。
不过有一点需求紧记:运用什么函数创立的索引,也仅支撑相应函数走索引,比方上面经过了
upper()
函数创立了一个索引,因而upper(c1) = 'ABC'
这种状况能够走索引,但运用其他函数时仍旧会导致索引失效,如:lower(c1) = 'abc'
。
3.6、CTE通用表表达式(Common Table Expression)
首要要搞了解这个称号,不是通用表达式,而是通用表、表达式,这个称号上有许多人都叫成通用表达式、公用表达式,这明显是不正确的,由于直接将其间的Table
省去了,所以我们在这儿要紧记,正确的叫法应该是通用表表达式。
CTE
通用表表达式究竟是用来干什么工作的呢?CTE
是一个具有变量名的暂时成果集,也便是能够将一条查询句子的成果保存到一个变量里面,后续在其他句子中答应直接经过变量名来运用该成果集,语法如下:
with CTE称号
as (查询句子/子查询句子)
select 句子;
上述的语法是一个一般的CTE
用法,一起还有另一种递归的CTE
用法,先举个简略的比如来认识一下最基本的用法:
-- MySQL8.0版别之前的子查询句子
select * from t1 where xx in (select xx from t2 where yy = "zzz");
-- MySQL8.0中运用CTE表达式来代替
with cte_query as
(select xx from t2 where yy = "zzz")
select * from t1 join cte_query on t1.xx = cte_query.xx;
调查上述比如,本来句子中需求运用in
来对子查询的多个成果集做匹配,运用CTE
后能够将子查询的成果集保存在cte_query
变量中,后续的句子中能够将其当作成一张表,然后来做衔接查询。
其实看到这儿,
CTE
表达式是不是有些类似于暂时表的概念?但它会比暂时表更轻,查询更快。
除开最基本的表达式外,还有一种名为递归CTE
表达式的概念,它是一种递归算法的完结,能够重复履行一段SQL
,比方当你要查询标签表中,某个尖端标签下悉数的子标签时,它的下级或许也存在其它字标签…..,或许一个尖端标签下面有十八层子标签,这时经过传统的查询句子就无法很好完结,而运用递归的CTE
表达式就很简略啦。
递归CTE
表达式只需求运用with recursive
关键字即可,不过这儿我不贴具体完结啦,我们感兴趣的可自行研讨了解CTE
后再完结该需求。
CTE
表达式除开能够与select
句子嵌套外,还能够与其它类型的句子嵌套,例如:with delete、with update、with recursive、with with、insert with
等,我们感兴趣的也可自行研讨,总归CTE
在许多状况下的确比较实用~
3.7、窗口函数(Window Function)
窗口函数可谓是MySQL8.0
中最大的亮点之一,但在测验去学习时会发现很难了解,先来看看窗口函数的界说。
窗口函数是一种剖析型的OLAP
函数,因而也被称之为剖析函数,它能够了解成是数据的调集,类似于group by
分组的功用,但之前的MySQL
版别依据某个字段分组后,会将数据紧缩到一行显现,如下:
select * from `zz_users`;
+---------+-----------+----------+----------+---------------------+
| user_id | user_name | user_sex | password | register_time |
+---------+-----------+----------+----------+---------------------+
| 1 | 熊猫 | 女 | 6666 | 2022-08-14 15:22:01 |
| 2 | 竹子 | 男 | 1234 | 2022-09-14 16:17:44 |
| 3 | 子竹 | 男 | 4321 | 2022-09-16 07:42:21 |
| 4 | 猫熊 | 女 | 8888 | 2022-09-17 23:48:29 |
+---------+-----------+----------+----------+---------------------+
select user_id from zz_users group by user_sex;
+-----------+
| user_id |
+-----------+
| 1,4 |
| 2,3 |
+-----------+
而窗口函数则不会将数据紧缩成一行,也便是表中数据本来是多少行,分组完结后仍旧是多少行,窗口函数的语法如下:
[window 窗口函数名 as (window_spec) [, 窗口函数名 AS (window_spec)] ...]
窗口函数名(窗口名/表达式)
over (
[partition_defintion]
[order_definition]
[frame_definition]
)
其实这个语法看起来不是特别能让人了解,所以结合具体的场景来举例,语法如下:
窗口函数 over([partition by 字段名 order by 字段名 asc|desc])
窗口函数 over 窗口名 ... window 窗口名
as ([partition by 字段名 order by 字段名 asc|desc])
一眼看下来,成果仍是令人不了解,对吗?这先别急,看不懂也没联系,后面会举例说明,先来看看MySQL8.0
中供给了哪些窗口函数呢?如下:
- 序号函数:
-
row_number()
:按序排列,相同的值序号会往后推,如88、88、89
排序为1、2、3
。 -
rank()
:并列排序,相同的值序号会跳过,如88、88、89
排序为1、1、3
。 -
dense_rank()
:并列排序,相同的值序号不会跳过,如88、88、89
排序为1、1、2
。
-
- 散布函数:
-
percent_rank()
:计算当时行数据的某个字段值占窗口内某个字段悉数值的百分比。 -
cume_dist()
: 小于等于当时字段值的行数与整个分组内悉数行数据的占比。
-
- 前后函数:
-
lag(expr,n)
:回来分组中的前n
条契合expr
条件的数据。 -
lead(expr,n)
:回来分组中的后n
条契合expr
条件的数据。
-
- 首尾函数:
-
first_value(expr)
:回来分组中的第一条契合expr
条件的数据。 -
last_value(expr)
:回来分组中的最后一条契合expr
条件的数据。
-
- 其它函数:
-
nth_value(expr,n)
:回来分组中的第n
条契合expr
条件的数据。 -
ntile(n)
:将一个分组中的数据再分成n
个小组,并记载每个小组编号。
-
这样看过去好像也有些令人模糊,究竟之前对窗口函数则这块接触比较少,因而下面来举个简略的比如切身感受一下(仍是以之前的用户表为例),需求如下:
- 按性别分组,并依照
ID
值从大到小对各分组中的数据进行排序,最后输出。
这需求一听就知道一条SQL
肯定搞不定,在之前版别中需求创立暂时表来完结,凭借暂时表来拆成多步完结,而在MySQL8.0
中则能够凭借窗口函数轻松完结,如下:
select
-- 运用 row_number() 序号窗口函数
row_number() over(
-- 依据性别做分组,然后依据 ID 做倒序
partition by user_sex order by user_id desc
) as serial_num,
user_id, user_name, user_sex, password, register_time
from
zz_users;
+------------+---------+-----------+----------+----------+---------------------+
| serial_num | user_id | user_name | user_sex | password | register_time |
+------------+---------+-----------+----------+----------+---------------------+
| 1 | 4 | 猫熊 | 女 | 8888 | 2022-09-17 23:48:29 |
| 2 | 1 | 熊猫 | 女 | 6666 | 2022-08-14 15:22:01 |
| 1 | 3 | 子竹 | 男 | 4321 | 2022-09-16 07:42:21 |
| 2 | 2 | 竹子 | 男 | 1234 | 2022-09-14 16:17:44 |
+------------+---------+-----------+----------+----------+---------------------+
上述这条SQL
便是依据序号窗口函数的完结,其实发现会尤为简略,调查履行成果也会发现,运用窗口函数分组后,并不会将数据紧缩到一行,而是将同一分组的数据在成果会集相邻显现。
上面的比如中就演示了最为简略的窗口函数用法:
函数名() over(数据处理)
,但实践状况中能够灵敏的依据需求变化,但如若想要很好的运用窗口函数,那还需求我们多加以操练,关于这块我们可参阅《MySQL官网-窗口函数示例》、或《宋红康教师的视频教育》。
3.8、MySQL8.0中的其他特性
在前面的内容中,就现已将MySQL8.0
中较为重要的改动和特性做了具体论述,但MySQL8.0
全体的改动也比较大,因而这儿再列出一些其它方面的特性,如下:
- 将默许的
UTF-8
编码格局从latin
替换成了utf8mb4
,后者包括了悉数emoji
表情包字符。 - 增强
NoSQL
存储功用,优化了5.6
版别引进的NoSQL
技能,并完善了对JSON
的支撑性。 -
InnoDB
引擎再次增强,对自增、索引、加密、死锁、同享锁等方面做了许多改善与优化。 - 支撑界说原子
DDL
句子,即当需求对库表结构产生改动时,改动操作可界说为原子性操作。 - 支撑正则检索,新增
REGEXP_LIKE()、EGEXP_INSTR()、REGEXP_REPLACE()、REGEXP_SUBSTR()
等函数供给支撑。 - 优化暂时表,暂时表默许引擎从
Memory
替换为TempTable
引擎,资源开支少,功用更强。 - 锁机制增强,除开前面聊到的锁特性改动外,新引进了一种备份锁,获取/开释锁语法如下:
- 获取锁:
LOCK INSTANCE FOR BACKUP
、开释锁:UNLOCK INSTANCE
- 获取锁:
-
Bin-log
日志增强,过期时刻准确到秒,使用zstd
算法增强了日志事务的紧缩功用。 - 安全性进步,认证加密插件更新、暗码战略改善、新增人物功用、日志文件支撑加密等。
- 引进资源组的概念,支撑按事务优先级来操控作业线程的
CPU
资源抢占几率。
.......
:更多请参阅《MySQL官网-8.0版手册》。
四、MySQL特性篇总结
在这章中我们介绍了MySQL
几个重要的里程碑版别,明显每个版别中都对前版别中做了不小的优化,尤其是MySQL8.0
中的新特性和新优化点非常具有吸引力。但线上环境已有数据的状况下,也不适合再做搬迁,究竟数据搬迁是一件非常麻烦的工作,有时候乃至比你重构一个Java
项目更累,因而假如你的数据库版别现在足以支撑体系的正常工作,那就没有必要去做版别搬迁。
但如若你的项目数据库现已抵达瓶颈,而且晋级数据库版别着实能够处理现在的困扰,这种状况下则能够测验晋级数据库版别,将旧版别的数据搬迁到新版别的数据库中,但这类作业在有专业人士负责的状况下,最好不要自己去插手,究竟一些企业中会有专门的
DBA
方向。
最后,在本章节中也仅介绍了一些较为重要的新特性和优化项,但MySQL
每个版别中都有一些修修补补的小特性、小改善,这儿就不打开叙说了,我们感兴趣的可直接翻阅MySQL
官网供给的手册,以此来具体得知各个版别中的细节改善。