展开
拓展 关闭
订阅号推广码
GitHub
视频
公告栏 关闭

MySQL8.0索引新特性

持降序索引

  • 在MySQL5.7和MySQL8.0中创建表
CREATE TABLE ts1(a int,b int,index idx_a_b(a,b desc));

# 在MySQL5.7中查看表结构
show create table ts1\G
# 索引仍然是默认的升序

# 在MySQL8.0中查看表结构
show create table ts1\G
# 索引是降序的
  • 分别在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 5.7版本中查看数据表ts1
# 执行计划中扫描数为5,而且没有使用Using filesor
# 降序索引只对查询中特定的排序顺序有效,如果使用不当,反而查询效率更低

# 例如,上述查询排序条件改为order by a desc, b desc,MySQL 5.7的执行计划要明显好于MySQL 8.0
EXPLAIN SELECT * FROM ts1 ORDER BY a DESC,b DESC LIMIT 5;

隐藏索引

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

从MySQL 8.x开始支持 隐藏索引(invisible indexes),只需要将待删除的索引设置为隐藏索引,使查询优化器不再使用这个索引
(即使使用force index(强制使用索引),优化器也不会使用该索引),确认将索引设置为隐藏索引后系统不受任何响应,就可以彻底删除索引。 
这种通过先将索引设置为隐藏索引,再删除索引的方式就是软删除
  • 创建表时,直接创建隐藏索引
# 关键字INVISIBLE,用来标记索引为不可见索引
CREATE TABLE tablename(
propname1 type1[CONSTRAINT1],
propname2 type2[CONSTRAINT2],
……
propnamen typen,
INDEX [indexname](propname1 [(length)]) INVISIBLE
);
  • 表已存在,设置隐藏索引
CREATE INDEX indexname ON tablename(propname[(length)]) INVISIBLE;
  • 通过ALTER TABLE语句创建
ALTER TABLE tablename
ADD INDEX indexname (propname [(length)]) INVISIBLE;
  • 切换索引可见状态
# 当索引被隐藏时,它的内容仍然是和正常索引一样实时更新的。如果一个索引需要长期被隐藏,
那么可以将其删除,因为索引的存在会影响插入、更新和删除的性能
ALTER TABLE tablename ALTER INDEX index_name INVISIBLE;   # 切换成隐藏索引
ALTER TABLE tablename ALTER INDEX index_name VISIBLE;   # 切换成非隐藏索引
  • 使隐藏索引对查询优化器可见
在MySQL 8.x版本中,为索引提供了一种新的测试方式,可以通过查询优化器的一个开关(use_invisible_indexes)来打开某个设置,
使隐藏索引对查询优化器可见。如果 use_invisible_indexes设置为off(默认),优化器会忽略隐藏索引。如果设置为on,即使隐藏索引不可见,
优化器在生成执行计划时仍会考虑使用隐藏索引
  • 查看查询优化器的开关设置
select @@optimizer_switch \G

# 输出信息配置值为off,说明隐藏索引默认对查询优化器不可见
use_invisible_indexes=off
  • 使隐藏索引对查询优化器可见
set session optimizer_switch="use_invisible_indexes=on";

# 再次查看
select @@optimizer_switch \G

# 输出信息use_invisible_indexes属性的值为on,说明此时隐藏索引对查询优化器可见
use_invisible_indexes=on
  • 测试
# 使用EXPLAIN查看以字段invisible_column作为查询条件时的索引使用情况
explain select * from classes where cname = '高一2班';

# 查询优化器会使用隐藏索引来查询数据
posted @ 2022-06-13 10:35  DogLeftover  阅读(63)  评论(0编辑  收藏  举报