MySQL8.0索引新特性

MySQL8.0索引新特性

支持降序索引

降序索引以降序存储键值。虽然在语法上,从MySQL 4版本开始就已经支持降序索引的语法了,但实际上该DESC定义是被忽略的,直到MySQL 8.x版本才开始真正支持降序索引(仅限于InnoDB存储引擎)。

MySQL在**8.0版本之前创建的仍然是升序索引,使用时进行反向扫描,这大大降低了数据库的效率。**在某些场景下,降序索引意义重大。例如,如果一个查询,需要对多个列进行排序,且顺序要求不一致,那么使用降序索引将会避免数据库使用额外的文件排序操作,从而提高性能。

举例:分别在MySQL 5.7版本和MySQL 8.0版本中创建数据表ts1,结果如下:

CREATE TABLE ts1(a int,b int,index idx_a_b(a,b desc));
SHOW CREATE TABLE ts1;

MySQL8.0创建的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6c7e3Ipr-1647869743579)(C:/Users/losser/AppData/Roaming/Typora/typora-user-images/image-20220320104032912.png)]

MySQL5.7创建的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XSJKUqfa-1647869743580)(C:/Users/losser/AppData/Roaming/Typora/typora-user-images/image-20220320104201932.png)]

分别在MySQL 5.7版本和MySQL 8.0版本的数据表ts1中插入800条随机数据,执行语句如下:

DELIMITER //
CREATE PROCEDURE ts_insert()
BEGIN
DECLARE i INT DEFAULT 1;
WHILE i < 800
DO
insert into ts1 select rand()*80000,rand()*80000;
SET i = i + 1;
END WHILE;
commit;
END //
DELIMITER ;
#调用
CALL ts_insert();

在MySQL 5.7版本中查看数据表ts1的执行计划,结果如下:

EXPLAIN SELECT * FROM ts1 ORDER BY a,b DESC LIMIT 5;

从结果可以看出,执行计划中扫描数为799,而且使用了Using filesort。

提示 Using filesort是MySQL中一种速度比较慢的外部排序,能避免是最好的。多数情况下,管理员
可以通过优化索引来尽量避免出现Using filesort,从而提高数据库执行速度。

在MySQL 8.0版本中查看数据表ts1的执行计划。从结果可以看出,执行计划中扫描数为5,而且没有使用
Using filesort。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p0zBJGKp-1647869743581)(C:/Users/losser/AppData/Roaming/Typora/typora-user-images/image-20220320105030802.png)]

注意 降序索引只对查询中特定的排序顺序有效,如果使用不当,反而查询效率更低。例如,上述
查询排序条件改为order by a desc, b desc,MySQL 5.7的执行计划要明显好于MySQL 8.0。

隐藏索引

在MySQL 5.7版本及之前,只能通过显式的方式删除索引。此时,如果发现删除索引后出现错误,又只能
通过显式创建索引的方式将删除的索引创建回来。如果数据表中的数据量非常大,或者数据表本身比较
大,这种操作就会消耗系统过多的资源,操作成本非常高。

从MySQL 8.x开始支持隐藏索引(invisible indexes) ,只需要将待删除的索引设置为隐藏索引,使
查询优化器不再使用这个索引(即使使用force index(强制使用索引),优化器也不会使用该索引),
确认将索引设置为隐藏索引后系统不受任何响应,就可以彻底删除索引。这种通过先将索引设置为隐藏索 引,再删除索引的方式就是软删除

注意:
主键不能被设置为隐藏索引。当表中没有显式主键时,表中第一个唯一非空索引会成为隐式主键,也不能设置为隐藏索引。

索引默认是可见的,在使用CREATE TABLE,CREATE INDEX或者ALTER TABLE等语句时可以通过VISIBLE或者INVISIBLE关键词设置索引的可见性。

创建表时,创建隐藏索引:

DROP TABLE book7;
CREATE TABLE book7(
book_id INT  ,
book_name VARCHAR(100),
AUTHORS VARCHAR(100),
info VARCHAR(100) ,
COMMENT VARCHAR(100),
year_publication YEAR,
# 创建不可见索引
INDEX idx_cmt(COMMENT) invisible
);
SHOW INDEX FROM book7;

创建表之后创建隐藏索引

ALTER TABLE book7
ADD UNIQUE KEY uk_idx_bname(book_name) invisible;

SHOW INDEX FROM book7;

CREATE INDEX idx_year ON book7(year_publication) invisible;

修改索引的可见性

# 修改索引的可见性
ALTER TABLE book7 ALTER INDEX idx_year invisible;
ALTER TABLE book7 ALTER INDEX idx_year visible;

如果将index_cname索引切换成可见状态,通过explain查看执行计划,发现优化器选择了index_cname索
引。

注意 当索引被隐藏时,它的内容仍然是和正常索引一样实时更新的。如果一个索引需要长期被隐
藏,那么可以将其删除,因为索引的存在会影响插入、更新和删除的性能。

使隐藏索引对查询优化器可见

在MySQL 8.x版本中,为索引提供了一种新的测试方式,可以通过查询优化器的一个开关(use_invisible_indexes)来打开某个设置,使隐藏索引对查询优化器可见。如果 use_invisible_indexes
设置为off(默认),优化器会忽略隐藏索引。如果设置为on,即使隐藏索引不可见,优化器在生成执行计
划时仍会考虑使用隐藏索引

  1. 在MySQL命令行执行如下命令查看查询优化器的开关设置
select @@optimizer_switch \G

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ulrvg6qF-1647869743581)(C:/Users/losser/AppData/Roaming/Typora/typora-user-images/image-20220320111729396.png)]

此属性配置值为off,说明隐藏索引默认对查询优化器不可见。

  1. 使隐藏索引对查询优化器可见,需要在MySQL命令行执行如下命令:
set session optimizer_switch="use_invisible_indexes=on";

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eBVVV4w8-1647869743582)(C:/Users/losser/AppData/Roaming/Typora/typora-user-images/image-20220320112046258.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zPW1VUmH-1647869743582)(C:/Users/losser/AppData/Roaming/Typora/typora-user-images/image-20220320112137301.png)]

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值