关于mysql8.0新特性的一些简单总结

在前面的文章中分享了一些mysql升级到8.0.x的一些实际做法,这里对mysql8.0.x的一些新特性或者是改良优化的地方做一些简单总结,可能涉及的方面不全或者个人理解不一样,见谅

參考参考官网:MySQL :: MySQL 8.0 参考手册https://dev.mysql.com/doc/refman/8.0/en/

1、隐藏索引

隐藏索引的特性对于性能调试非常有用。在 8.0 中,索引可以被"隐藏"和"显示"。当一个索引隐藏时,它不会被查询优化器所使用。

也就是说可以隐藏一个索引,然后观察对数据库的影响。如果数据库性能有所下降,就说明这个索引是有用的,于是将其"恢复显示"即可;如果数据库性能看不出变化,说明这个索引是多余的,可以删掉了。

隐藏一个索引的语法是:

sql 复制代码
ALTER TABLE t ALTER INDEX i INVISIBLE;

恢复显示该索引的语法是:

sql 复制代码
ALTER TABLE t ALTER INDEX i VISIBLE;

当一个索引被隐藏时,我们可以从 show index 命令的输出中看到,该索引的 Visible 属性值为 NO。也就是说这个索引其实是存在的。

**注意:**当索引被隐藏时,它的内容仍然是和正常索引一样实时更新的,这个特性本身是专门为优化调试使用。如果你长期隐藏一个索引,那还不如干脆删掉,因为毕竟索引的存在会影响插入、更新和删除的性能。

2、UTF-8 编码

从 MySQL 8 开始,数据库的缺省编码将改为 utf8mb4(之前是latin)这个编码包含了所有 emoji 字符

3、通用表表达式CTE

复杂的查询会使用嵌入式表,例如:

sql 复制代码
SELECT t1.*, t2.* FROM
 (SELECT col1 FROM table1) t1,
 (SELECT col2 FROM table2) t2;

而有了 CTE,我们可以这样写:

sql 复制代码
WITH
 t1 AS (SELECT col1 FROM table1),
 t2 AS (SELECT col2 FROM table2)
SELECT t1.*, t2.* 
FROM t1, t2;

并且还支持了递归相关的语法。

4、窗口函数(Window Functions)

当需要在查询当中实现排名时,必须手写 @ 变量。但是从 8.0 开始,MySQL 新增了一个叫窗口函数的概念,它可以用来实现若干新的查询方式。

窗口函数有点像是 SUM()、COUNT() 那样的集合函数,但它并不会将多行查询结果合并为一行,而是将结果放回多行当中。也就是说,窗口函数是不需要 GROUP BY 的。

sql 复制代码
select *,rank() over w as `rank` from users window w as (order by u_count);

说明:在这里创建了名为 w 的 window,规定它对 u_count 字段进行排序,然后在 select 子句中对 w 执行 rank() 方法,将结果输出为 rank 字段。

注:但是感觉日常开发中,我们更习惯是先进行查询然后自己排序后通过后台程序给一个rank值,这个功能用处暂时不咋看到。

5、秒级加列

  • 只改数据字典表元数据信息
  • 5.7和8.0 sbteset1表数据分别为3000w
sql 复制代码
# mysql8.0.18
mysql> alter table sbtest1 add str varchar(200) not null default 'mysql8.0 新加字段';
Query OK, 0 rows affected (0.13 sec)
Records: 0  Duplicates: 0  Warnings: 0

# mysql5.7.16
mysql>  alter table sbtest1 add str varchar(200) not null default 'mysql5.7 新加字段';
Query OK, 0 rows affected (6 min 8.36 sec)
Records: 0  Duplicates: 0  Warnings: 0

以前表加列操作需要重建表(消耗大量的IO资源和时间),现在可以快速的增加字段,只修改数据字典,而不用修改表中的记录本身。所以8.0加列没有这个步骤。秒级加列(不要指定列位置,如after str1)

6、性能提升

有一些对于查询或者统计相关的速度优化。

sql 复制代码
# mysql5.7.16
mysql> select count(*) from sbtest1;
+----------+
| count(*) |
+----------+
| 29991137 |
+----------+
1 row in set (3 min 12.24 sec)

# mysql8.0.18
mysql> select count(*) from sbtest1;
+----------+
| count(*) |
+----------+
| 30000000 |
+----------+
1 row in set (45.70 sec)

分别在只更新和只读场景下,8.0相比5.7在高并发时性能提升近1倍;求表总数据量8.0响应时间也将近提升5倍

7、Json加强

在Json上,8.0 增加了更多的功能性。支持更新JSON中部分字段

8、查询lock优化

  • SKIP LOCKED

需要加锁的记录若被其它线程占有锁,则跳过,而不是等待

sql 复制代码
select * from tx where c1=12 for update skip locked;
Empty set (0.00 sec)
  • NOWAIT需要加锁的记录有锁则报错

需要加锁的记录有锁则报错

sql 复制代码
select * from tx where c1=12 for update nowait;
ERROR 3572 (HY000): Statement aborted because lock(s) could not be acquired immediately and NOWAIT is set.

其实这个特性感觉对死锁或者锁循环导致一直阻塞会有用,还有在一些秒杀等大流量场景也可以

9、角色管理

角色可以认为是一些权限的集合,为用户赋予统一的角色,权限的修改直接通过角色来进行,无需为每个用户单独授权。

10、函数索引

MySQL 8.0.13 以及更高版本支持函数索引(functional key parts),也就是将表达式的值作为索引的内容,而不是列值或列值前缀。 将函数作为索引键可以用于索引那些没有在表中直接存储的内容。

其实MySQL5.7中推出了虚拟列的功能,而MySQL8.0的函数索引也是依据虚拟列来实现的。

  • 只有那些能够用于计算列的函数才能够用于创建函数索引。
  • 函数索引中不允许使用子查询、参数、变量、存储函数以及自定义函数。
  • SPATIAL 索引和 FULLTEXT 索引不支持函数索引。

11、备份锁

在MySQL 8.0中,引入了一个轻量级的备份锁,这个锁可以保证备份一致性,而且阻塞的操作相对比较少,是一个非常重要的新特性。

在MySQL 8.0中,为了解决备份FTWRL的问题,引入了轻量级的备份锁;可以通过LOCK INSTANCE FOR BACKUP和UNLOCK INSTANCE,以获取和释放备份锁,执行该语句需要BACKUP_ADMIN权限。

backup lock不会阻塞读写操作。不过,backup lock会阻塞大部分DDL操作,包括创建/删除表、加/减字段、增/删索引、optimize/analyze/repair table等。

总的来说,备份锁还是非常实用的,毕竟其不会影响业务的正常读写;至于备份锁和DDL操作的冲突,还是有很多方法可以避免,比如错开备份和变更的时间、通过pt-online-schema-change/gh-ost避免长时间阻塞等等。随着备份锁的引入,Oracle官方备份工具MEB 8.0和Percona开源备份工具XtraBackup 8.0,也是更新了对backup lock的支持。

12、redo优化

mysql8.0一个新特性就是redo log提交的无锁化。在8.0以前,各个用户线程都是通过互斥量竞争,串行的写log buffer,因此能保证lsn的顺序无间隔增长。

mysql8.0通过redo log无锁化,解决了用户线程写redo log时竞争锁带来的性能影响。同时将redo log写文件、redo log刷盘从用户线程中剥离出来,抽成单独的线程,用户线程只负责将redo log写入到log buffer,不再关心redo log的落盘细节,只需等待log_writer线程或log_flusher线程的通知。

13、 关闭Query Cache

从 MySQL 8.0开始,不再使用查询缓存(Query Cache)。

随着技术的进步,经过时间的考验,MySQL的工程团队发现启用缓存的好处并不多。

首先,查询缓存的效果取决于缓存的命中率,只有命中缓存的查询效果才能有改善,因此无法预测其性能。

其次,查询缓存的另一个大问题是它受到单个互斥锁的保护。在具有多个内核的服务器上,大量查询会导致大量的互斥锁争用。

MySQL8.0取消查询缓存的另外一个原因是,研究表明,缓存越靠近客户端,获得的好处越大。MySQL8.0新增加了一些其他对性能干预的工具来支持。另外,还有像ProxySQL这样的第三方工具,也可以充当中间缓存。

剩余的还有一些例如用户修改密码,安全性保障等等,GIS信息的优化等

相关推荐
你的微笑,乱了夏天10 分钟前
linux centos 7 安装 mongodb7
数据库·mongodb
工业甲酰苯胺22 分钟前
分布式系统架构:服务容错
数据库·架构
独行soc1 小时前
#渗透测试#漏洞挖掘#红蓝攻防#护网#sql注入介绍08-基于时间延迟的SQL注入(Time-Based SQL Injection)
数据库·sql·安全·渗透测试·漏洞挖掘
White_Mountain2 小时前
在Ubuntu中配置mysql,并允许外部访问数据库
数据库·mysql·ubuntu
Code apprenticeship2 小时前
怎么利用Redis实现延时队列?
数据库·redis·缓存
百度智能云技术站2 小时前
广告投放系统成本降低 70%+,基于 Redis 容量型数据库 PegaDB 的方案设计和业务实践
数据库·redis·oracle
老王笔记2 小时前
GTID下复制问题和解决
mysql
装不满的克莱因瓶2 小时前
【Redis经典面试题六】Redis的持久化机制是怎样的?
java·数据库·redis·持久化·aof·rdb
Lojarro3 小时前
【Spring】Spring框架之-AOP
java·mysql·spring
梦想平凡3 小时前
PHP 微信棋牌开发全解析:高级教程
android·数据库·oracle