MySQL8新特性-索引增强

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做了限制)

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;

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中相当于新增了一个列,这个列会根据你的函数来进行计算结果,然后使用函数索引的时候就会用这个计算后的列作为索引。

猜你喜欢

转载自blog.csdn.net/m0_70299172/article/details/130496256
今日推荐