1. MySQL8新特性
关于 MySQL 5.7 版别,其将于 2023年 10月31日 停止支撑。后续官方将不再进行后续的代码保护。
MySQL 8.0 全内存访问能够轻易跑到 200W QPS,I/O 极点高负载场景跑到 16W QPS,除此之外MySQL 8还新增了许多功用,那么咱们来一起看一下。
1.1. 账户与安全
1.1.1. 用户创立和授权
到了MySQL8中,用户创立与授权句子必须是分隔履行,之前版别是能够一起履行。
MySQL8的版别
grant all privileges on *.* to 'lijin'@'%' identified by 'Lijin@2022';
create user 'lijin'@'%' identified by 'Lijin@2022';
grant all privileges on *.* to 'lijin'@'%';
MySQL5.7的版别
grant all privileges on *.* to 'lijin'@'%' identified by 'Lijin@2022';
1.1.2. 认证插件更新
MySQL 8.0中默认的身份认证插件是caching_sha2_password,替代了之前的mysql_native_password。
show variables like 'default_authentication%';
5.7版别
8版别
select user, host,plugin from mysql.user;
这个带来的问题便是假如客户端没有更新,就衔接不上!!
当然能够经过在MySQL的服务端找到my.cnf的文件,把相关参数进行修正(不过要MySQL重启后才干收效)
假如没办法重启服务,还有一种动态的方法:
alter user 'lijin'@'%' identified with mysql_native_password by 'Lijin@2022';
select host,user from mysql.user;
运用老的Navicat for MySQL也能访问
1.1.3. 暗码管理
MySQL 8.0开端答应限制重复运用曾经的暗码(修正暗码时)。
而且还加入了暗码的修正管理功用
show variables like 'password%';
修正战略(全局级)
set persist password_history=3; --修正暗码不能和最近3次共同
修正战略(用户级)
alter user 'lijin'@'%' password history 3;
select user, host,Password_reuse_history from mysql.user;
运用重复暗码修正用户暗码(指定lijin用户)
alter user 'lijin'@'%' identified by 'Lijin@2022';
假如咱们把全局的参数改为0,则关于root用户能够重复的修正暗码
alter user 'root'@'localhost' identified by '789456';
password_reuse_interval 则是依照天数来限定(不答应重复的)
password_require_current 是否需求校验旧暗码(off 不校验、 on校验)(针对非root用户)
set persist password_require_current=on;
1.2. 索引增强
1.2.1. 躲藏索引
MySQL 8.0开端支撑躲藏索引 (invisible index),不可见索引.
躲藏索引不会被优化器运用,但仍然需求进行保护。 运用场景: 软删去、灰度发布。
软删去:便是咱们在线上会常常删去和创立索引,假如是曾经的版别,咱们假如删去了索引,后面发现删错了,我又需求创立一个索引,这样做的话就非常影响功用。在MySQL8中咱们能够这么操作,把一个索引变成躲藏索引(索引就不可用了,查询优化器也用不上),最终确定要进行删去这个索引咱们才会进行删去索引操作。
灰度发布:也是相似的,咱们想在线上进行一些测验,能够先创立一个躲藏索引,不会影响当前的生产环境,然后咱们经过一些附加的测验,发现这个索引没问题,那么就直接把这个索引改成正式的索引,让线上环境收效。
运用事例(灰度发布):
create table t1(i int,j int); --创立一张t1表
create index i_idx on t1(i); --创立一个正常索引
create index j_idx on t1(j) invisible; --创立一个躲藏索引
show index from t1\G --检查索引信息
运用查询优化器看下:
explain select * from t1 where i=1;
explain select * from t1 where j=1;
这儿能够看到躲藏索引不会用上。
这儿能够经过优化器的开关,翻开一个设置,便利咱们对躲藏索引进行设置。
select @@optimizer_switch\G; --检查 各种参数
红色的部分便是默认查询优化器对躲藏索引不可见,咱们能够经过参数进行修正。保证咱们能够用躲藏索引进行测验。
set session optimizer_switch="use_invisible_indexes=on'; --在会话等级设置查询优化器能够看到躲藏索引
再运用查询优化器看下:
explain select * from t1 where j=1;
把躲藏索引变成可见索引(正常索引)
alter table t1 alter index j_idx visible; --变成可见
alter table t1 alter index j_idx invisible; --变成不可见(躲藏索引)
最终一点,不能把主键设置成不可见的索引(躲藏索引)(MySQL做了限制)
1.2.2. 降序索引
MySQL 8.0开端真正支撑降序索引 (descendingindex) 。只有InnoDB存储引擎支撑降序索引,只支撑BTREE降序索引。别的MySQL8.0不再对GROUP BY操作进行隐式排序。
在MySQL中创立一个t2表
create table t2(c1 int,c2 int,index idx1(c1 asc,c2 desc));
show create table t2\G
假如是5.7中,则没有显示升序仍是降序信息
咱们插入一些数据,给大家演示下降序索引的运用
insert into t2(c1,c2) values(1,100),(2,200),(3,150),(4,50);
看下索引运用情况
explain select * from t2 order by c1,c2 desc;
咱们在5.7对比一下
这儿说明,这儿需求一个额定的排序操作,才干把刚才的索引利用上。
咱们把查询句子换一下
explain select * from t2 order by c1 desc,c2 ;
MySQL8中运用了
别的还有一点,便是group by句子在 8之后不再默认排序
select count(*),c2 from t2 group by c2;
在8要排序的话,就需求手动把排序句子加上
select count(*),c2 from t2 group by c2 order by c2;
1.2.3. 函数索引
之前咱们知道,假如在查询中加入了函数,索引不收效,所以MySQL8引入了函数索引。
MySQL 8.0.13开端支撑在索引中运用函数(表达式)的值。支撑降序索引,支撑JSON 数据的索引 函数索引基于虚拟列功用完成。
运用函数索引(表达式)
create table t3(c1 varchar(10),c2 varchar(10));
create index idx_c1 on t3(c1); --一般索引
create index func_idx on t3( (UPPER(c2)) ); --一个大写的函数索引
show index from t3\G
explain select * from t3 where upper(c1)='ABC' ;
explain select * from t3 where upper(c2)='ABC' ;
运用函数索引(JSON)
create table t4(data json,index((CAST(data->>'$.name' as char(25)) )));
explain select * from t4 where CAST(data->>'$.name' as char(25)) = 'lijin ';
函数索引基于虚拟列功用完成
函数索引在MySQL中相当于新增了一个列,这个列会根据你的函数来进行核算成果,然后运用函数索引的时分就会用这个核算后的列作为索引。
1.3. 通用表表达式(CTE)
MySQL8.0开端支撑通用表表达式(CTE)(common table expression),即WITH子句。
简略入门:
以下SQL便是一个简略的CTE表达式,相似于递归调用,这段SQL中,首先履行select 1 然后得到查询成果后把这个值n送入 union all下面的 select n+1 from cte where n <10,然后一向这样递归调用union all下面sql句子。
WITH recursive cte(n) as
( select 1
union ALL
select n+1 from cte where n<10
)
select * from cte;
事例介绍:
一个staff表,里面有id,有name还有一个 m_id,这个是对应的上级id。数据如下:
假如咱们想查询出每一个员工的上下级关系,能够运用以下方法
递归CTE:
with recursive staff_view(id,name,m_id) as
(select id ,name ,cast(id as char(200))
from staff where m_id =0
union ALL
select s2.id ,s2.name,concat(s1.m_id,'-',s2.id)
from staff_view as s1 join staff as s2
on s1.id = s2.m_id
)
select * from staff_view order by id
运用通用表表达式的优点便是上下级层级就算有4,5,6甚至更多层,都能够帮助咱们遍历出来,而老的方法的写法SQL句子就要调整。
总结:
通用表表达式与派生表相似,就像句子等级的暂时表或视图。CTE能够在查询中屡次引证,能够引证其他CTE,能够递归。CTE支撑SELECT/INSERT/UPDATE/DELETE等句子。
1.4. 窗口函数
MySQL 8.0支撑窗口函数(Window Function),也称剖析函数。窗口函数与分组聚合函数相似,但是每一行数据都生成一个成果。聚合窗口函数: SUM /AVG / COUNT /MAX/MIN等等。
事例如下:sales表结构与数据如下:
一般的分组、聚合(以国家核算)
SELECT country,sum(sum)
FROM sales
GROUP BY country
order BY country;
窗口函数(以国家汇总)
select year,country,product,sum,
sum(sum) over (PARTITION by country) as country_sum
from sales
order by country,year,product,sum;
窗口函数(核算平局值)
select year,country,product,sum,
sum(sum) over (PARTITION by country) as country_sum,
avg(sum) over (PARTITION by country) as country_avg
from sales
order by country,year,product,sum;
专用窗口函数:
- 序号函数:ROW_NUMBER()、RANK()、DENSE_RANK()
- 分布函数:PERCENT_RANK()、CUME_DIST()
- 前后函数:LAG()、LEAD()
- 头尾函数:FIRST_VALUE()、LAST_VALUE()
- 其它函数:NTH_VALUE()、NTILE()
窗口函数(排名)
用于核算分类排名的排名窗口函数,以及获取指定方位数据的取值窗口函数
SELECT
YEAR,
country,
product,
sum,
row_number() over (ORDER BY sum) AS 'rank',
rank() over (ORDER BY sum) AS 'rank_1'
FROM
sales;
SELECT
YEAR,
country,
product,
sum,
sum(sum) over (PARTITION by country order by sum rows unbounded preceding) as sum_1
FROM
sales order by country,sum;
当然能够做的操作许多,详细见官网:
dev.mysql.com/doc/refman/…
1.5. 原子DDL操作
MySQL 8.0 开端支撑原子 DDL 操作,其中与表相关的原子 DDL 只支撑 InnoDB 存储引擎。一个原子 DDL 操作内容包含:更新数据字典,存储引擎层的操作,在 binlog 中记录 DDL 操作。支撑与表相关的 DDL:数据库、表空间、表、索引的 CREATE、ALTER、DROP 以及 TRUNCATE TABLE。支撑的其他 DDL :存储程序、触发器、视图、UDF 的 CREATE、DROP 以及ALTER 句子。支撑账户管理相关的 DDL:用户和角色的 CREATE、ALTER、DROP 以及适用的 RENAME,以及 GRANT 和 REVOKE 句子。
drop table t1,t2;
上面这个句子,假如只有t1表,没有t2表。在MySQL5.7与8 的表现是不同的。
5.7会删去t1表。而在8中由于报错了,整个是一个原子操作,所以不会删去t1表。
1.6. JSON增强
详细看官网信息,英文好的直接看,英文欠好的找个翻译东西即可看懂
MySQL :: MySQL 8.0 Reference Manual :: 11.5 The JSON Data Type
1.7. InnoDB其他改进功用
自增列耐久化
MySQL 5.7 以及早期版别,InnoDB 自增列计数器(AUTO_INCREMENT)的值只存储在内存中。MySQL 8.0 每次变化时将自增计数器的最大值写入 redo log,一起在每次检查点将其写入引擎私有的体系表。处理了长期以来的自增字段值或许重复的 bug。
死锁检查控制
MySQL 8.0 (MySQL 5.7.15)增加了一个新的动态变量,用于控制体系是否履行 InnoDB 死锁检查。关于高并发的体系,禁用死锁检查或许带来功用的提高。
innodb_deadlock_detect
锁定句子选项
SELECT … FOR SHARE 和 SELECT … FOR UPDATE 中支撑 NOWAIT、SKIP LOCKED 选项。关于 NOWAIT,假如恳求的行被其他业务锁定时,句子当即回来。关于 SKIP LOCKED,从回来的成果集中移除被锁定的行。
InnoDB 其他改进功用。
- 支撑部分快速 DDL,ALTER TABLE ALGORITHM=INSTANT;
- InnoDB 暂时表运用共享的暂时表空间 ibtmp1。
- 新增静态变量 innodb_dedicated_server,自动配置 InnoDB 内存参数:innodb_buffer_pool_size/innodb_log_file_size 等。
- 默认创立 2 个 UNDO 表空间,不再运用体系表空间。
- 支撑 ALTER TABLESPACE … RENAME TO 重命名通用表空间。
继续创造,加快生长!这是我参与「日新计划 10 月更文挑战」的第21天,点击检查活动概况