持降序索引
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();
EXPLAIN SELECT * FROM ts1 ORDER BY a,b DESC LIMIT 5;
# 执行计划中扫描数为799,而且使用了Using filesort
# Using filesort是MySQL中一种速度比较慢的外部排序,能避免是最好的。多数情况下,
管理员可以通过优化索引来尽量避免出现Using filesort,从而提高数据库执行速度
# 执行计划中扫描数为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 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班';
# 查询优化器会使用隐藏索引来查询数据