MySQL版本特性
MySQL8.0版本
在MySQL8.0发行前,基本上所有使用MySQL数据库的企业/个人项目,基本上都属于MySQL5.6/5.7的钉子户,基本上不会再选择除此之外的发行版,但随着MySQL8.0的发行,打破了这个局面,官方号称经压测后,8.0比5.7性能足足提升了200%,这无疑对于MySQL的忠实用户而言,显然是一个十分巨大的诱惑。 因为按照理论来说,只要你将项目中的MySQL,从原有的MySQL5.7版本升级到MySQL8.0版本,从数据库的性能上来说,无需你手动做任何优化,就能够让性能翻倍。 ### 1. 移除查询缓存(Query Cache) Query Cahce查询缓存的设计初衷很好,也就是利用热点探测技术,对于一些频繁执行的查询SQL,直接将结果缓存在内存中,之后再次来查询相同数据时,就无需走磁盘,而是直接从查询缓存中获取数据并返回。 听起来似乎还不错呀,好像确实能带来不小的性能提升呢?但实则很鸡肋,为啥? 因为MySQL查询缓存是以SQL的哈希值来作为Key的,一些细微的差别都会导致哈希值不同,如:user_id=1、user_id = 1,也就是一条SQL有空格,一条没有。由于这一点点细微差异,会导致两条SQL计算出的哈希值完全不同,因此无法命中缓存,是不是很鸡肋?还有多种情况:user_id =1、user_id= 1,空格处于的前后位置不同,也会导致缓存失效。 也正是由于方方面面的原因,所以查询缓存在MySQL8.0中被完全舍弃了,即移除掉了查询缓存区。 ### 2. 锁机制优化 在MySQL8.0中的锁机制主要出现了两点优化,一方面对获取共享锁的写法进行了优化,如下: ```sql -- MySQL8.0之前的版本 SELECT ... LOCK IN SHARE MODE; -- MySQL8.0及后续的版本 SELECT ... FOR SHARE; ``` 第二方面则支持非阻塞式获取锁机制,可以在获取锁的写法上加上NOWAIT、SKIP LOCKED关键字,这样在未获取到锁时不会阻塞等待,使用SKIP LOCKED未获取到锁时会直接返回空,使用NOWAIT会直接返回并向客户端返回异常。用法如下: ```sql select ... for update nowait; select ... for update skip locked; ``` ### 在线修改的系统参数支持持久化 在之前的版本中,通过set、set global的形式修改某个系统变量时,这种方式设置的参数值都是一次性的,也就是修改过的参数并不会被同步到本地,当MySQL重启时,这些调整过的参数又会回归默认值,如果想要让调整过的参数生效,就必须要手动停止MySQL,然后去修改my.ini/my.conf文件,修改完成后再重启数据库服务,这时才能让参数永久生效。 而在MySQL8.0中则彻底优化了这个问题,推出了在线修改参数后,支持持久化到本地文件的机制,也就是通过SET PERSIST命令来完成,如下: ```sql -- 调整事务的隔离级别(针对于当前连接有效) set transaction isolation level read uncommitted; -- 调整事务的隔离级别(针对于全局有效,重启后会丢失) set global tx_isolation = "read-committed"; -- 调整事务的隔离级别(针对于全局有效,并且会持久化到本地,重启后不会丢失) set persist global.tx_isolation = "repeatable-read"; ``` 通过set persist命令持久化的参数,可以通过下述命令来查看: ```sql select * from performance_schema.persisted_variables; ``` 这条命令的本质其实是:基于MySQL自带的performance_schema监控库查询持久化过的参数。 其实参数持久化的原理也非常简单,当执行set persist命令时,会将改变过的参数写入到本地的mysqld-auto.cnf文件中,MySQL每次启动时都会读取这个文件中的值,如果该文件中存在参数,则会直接将其加载,从而实现了一次修改,永久有效。 但当你想要参数不再持久化到本地时,可以选择删除安装目录下的mysqld-auto.cnf文件,或执行reset persist命令来清除,但这两种方式都只对下次重启时生效,毕竟本次参数已经被载入内存了,所以只能通过再次手动修改的方式复原。 ### 4. 增强多表连接查询 在之前的MySQL版本中,仅支持交叉连接、内连接、左外连接、右外连接四种连接类型,这四种连接都会采用默认的连接算法,而在8.0版本中提供了哈希连接、反连接两种连接优化的支持。 ### 5. 增强索引机制 在8.0中官方再一次对索引机制动刀,首先对联合索引提供了一种跳跃扫描机制的支持,也就意味着使用联合索引时,就算未遵循最左前缀匹配原则,也可以使用联合索引来检索数据。除此之外,还有另外三种新的索引特性:隐藏索引、降序索引以及函数索引。 ### 6. CTE通用表表达式(Common Table Expression) 首先要搞明白这个名称,不是通用表达式,而是通用表、表达式,这个名称上有许多人都叫成通用表达式、公用表达式,这显然是不正确的,因为直接将其中的Table省去了,所以大家在这里要牢记,正确的叫法应该是通用表表达式。 CTE通用表表达式究竟是用来干什么事情的呢?CTE是一个具备变量名的临时结果集,也就是可以将一条查询语句的结果保存到一个变量里面,后续在其他语句中允许直接通过变量名来使用该结果集,语法如下: ```sql with CTE名称 as (查询语句/子查询语句) select 语句; ``` ### 7. 窗口函数(Window Function) 窗口函数可谓是MySQL8.0中最大的亮点之一,但在尝试去学习时会发现很难理解,先来看看窗口函数的定义。 窗口函数是一种分析型的OLAP函数,因此也被称之为分析函数,它可以理解成是数据的集合,类似于group by分组的功能,但之前的MySQL版本基于某个字段分组后,会将数据压缩到一行显示,而窗口函数则不会将数据压缩成一行,也就是表中数据原本是多少行,分组完成后依旧是多少行,窗口函数的语法如下: ```sql [window 窗口函数名 as (window_spec) [, 窗口函数名 AS (window_spec)] ...] 窗口函数名(窗口名/表达式) over ( [partition_defintion] [order_definition] [frame_definition] ) ``` ### 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版手册》](https://dev.mysql.com/doc/refman/8.0/en/ "《MySQL官网-8.0版手册》")。
顶部
收展
底部
[TOC]
目录
MySQL5.6版本
MySQL5.7版本
MySQL8.0版本
相关推荐
MySQL教程
MySQL命令
MySQL索引
MySQL事务
MySQL锁机制