网站首页 > java教程 正文
0 前言
MySQL8.0开始支持隐藏索引,不可见索引。它允许快速启用/禁用MySQL Optimizer使用的索引。
隐藏索引不会被优化器使用,但仍需维护
1 应用场景
- 软删除
- 灰度发布,测试新索引 :在不影响现有查询性能的情况下,测试新创建的索引是否有效
- 维护索引 :在更新或重建索引时,可以先将其设置为不可见,避免影响在线查询
- 临时禁用无用索引 :如果某个索引不再被频繁使用,可以将其设置为不可见,减少不必要的开销
2 啥用?
若想删除一个索引,又想事先知道效果。可使它对优化程序不可见。这是一个快速的元数据更改,使索引不可见。一旦确定没有性能下降,就可真正去删除索引。
关键:隐藏索引不能供优化器使用,但它仍存在,并通过写入操作保持最新。即便尝试“FORCE INDEX”,优化器也不会用它,虽然我认为我们应该能在某种程度强制它。可能会有这样情况:
可创建一个新的隐形索引,但若想测试它,须使它可见。即所有对应用程序有即时影响的查询都将能用它。若目的只是想测试它,我不认为这是最好方法,不是所有人的服务器都有相同的数据大小和真实数据。强制隐藏索引这时可能会很有用。
你有许多索引,但不确定哪个未使用。可将一个索引更改为不可见,以查看是否存在任何性能下降。若是,你可立即更改。
可能有个特殊情况:只有一个查询可用该索引。此时,隐藏索引可能是很好解决方案。
3 创建
有两个选项:
3.1 创建一个具有隐藏索引的表
CREATE TABLE t1 (
i INT,
j INT,
k INT,
INDEX i_idx (i) INVISIBLE
) ENGINE = InnoDB;
CREATE INDEX j_idx ON t1 (j) INVISIBLE;
3.2 alter table并将索引更改为隐藏
ALTER TABLE t1 ADD INDEX k_idx (k) INVISIBLE;
4 使用
如果我们现在要删除索引,我们可以将其更改为隐藏。 但是使用“FORCE / USE INDEX”的查询怎么样? 他们是否会抛出一个错误? 如果强制不存在的索引,你会收到错误。 你不会看到隐藏索引的错误。 优化器不会使用它,但知道它存在。
show create table t1 G
*************************** 1. row ***************************
Table: t1
Create Table: CREATE TABLE `t1` (
`i` int(11) DEFAULT NULL,
`j` int(11) DEFAULT NULL,
`k` int(11) DEFAULT NULL,
KEY `i_idx` (`i`),
KEY `idx_1` (`i`,`j`,`k`)
) ENGINE=InnoDB DEFAULT CHARSET=latin11 row in set (0.00 sec)
mysql> explain select * from t1 force index(idx_1) where i=1 and j=4;
+----+-------------+-------+------------+------+---------------+-------+---------+-------------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+-------+---------+-------------+------+----------+-------------+
| 1 | SIMPLE | t1 | NULL | ref | idx_1 | idx_1 | 10 | const,const | 2 | 100.00 | Using index |
+----+-------------+-------+------------+------+---------------+-------+---------+-------------+------+----------+-------------+1 row in set, 1 warning (0.00 sec)
mysql> alter table t1 alter index idx_1 invisible;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0mysql> explain select * from t1 force index(idx_1) where i=1 and j=4;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| 1 | SIMPLE | t1 | NULL | ALL | NULL | NULL | NULL | NULL | 16 | 6.25 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+1 row in set, 1 warning (0.01 sec)
mysql> explain select * from t1 where i=1 and j=4;
+----+-------------+-------+------------+------+---------------+-------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+-------+---------+-------+------+----------+-------------+
| 1 | SIMPLE | t1 | NULL | ref | i_idx | i_idx | 5 | const | 2 | 10.00 | Using where |
+----+-------------+-------+------------+------+---------------+-------+---------+-------+------+----------+-------------+1 row in set, 1 warning (0.00 sec)
若用带有隐藏索引的“FORCE INDEX”,MySQL会执行全表扫描。 MySQL不会抛任何错误,因为索引存在,但不可见。 即使有另一个可用的索引,它也将执行全表扫描。
大型表上,这可能导致严重性能问题。 即使MySQL在查询执行期间不抛任何错误,它也应在错误日志中记录一个警告。
参考:
- 关于 MySQL 8.0 新特性“隐藏索引”的一点思考
- https://dev.mysql.com/doc/refman/8.0/en/invisible-indexes.html
本文已收录在Github,关注我,紧跟本系列专栏文章,咱们下篇再续!
- 魔都架构师 | 全网30W技术追随者
- 大厂分布式系统/数据中台实战专家
- 主导交易系统百万级流量调优 & 车联网平台架构
- AIGC应用开发先行者 | 区块链落地实践者
- 以技术驱动创新,我们的征途是改变世界!
- 实战干货:编程严选网
猜你喜欢
- 2025-07-09 SSM框架高并发和商品秒杀项目高并发秒杀API源码免费分享
- 2025-07-09 音乐盒Java在线音乐jsp源代码Mysql
- 2025-07-09 深入浅出JVM之如何定位线上JVM各种问题
- 2025-07-09 Java 近期新闻:Jakarta EE 11 发布、Agent2Agent Java SDK、Kotlin、WildFly
- 2025-07-09 java编程真的有必要学习吗?(学编程java是必要的嘛)
- 2025-07-09 Mysql修改表结构、添加索引会锁表吗?从MySQL5.7和8.0版本解析
- 2025-07-09 浪潮海岳智能物联网平台inIoT 8.0全新发布
- 2025-07-09 RubikFX:用JavaFX 3D解决魔方难题(1)
- 2025-07-09 Java新闻综述:Jakarta EE 11等发布。
- 2025-07-09 Java 新闻综述:Jakarta EE 11 发布、Agent2Agent Java SDK、Maven等
你 发表评论:
欢迎- 最近发表
-
- 你真的会用 Java 中的线程池吗?多个企业级线程池工具类封装实践
- 线程池的实现原理、优点与风险、以及四种线程池实现
- Java线程池ThreadPoolExecutor实现原理剖析
- 深入分析线程池的实现原理(线程池是干嘛的)
- 一文搞懂JAVA线程池工作原理(java线程池的工作流程)
- Java线程池的工作原理(java线程池的实现原理)
- 5分钟读懂C#中TcpClient、TcpListener和Socket三个类的角色
- JVM对象的创建过程(jvm运行过程中创建的对象一般存放在方法区)
- 对象组成与Java内存模型JMM分析(java对象在内存中存储的结构)
- JVM对象内存分配详细过程(栈上分配->TLAB->老年代->Eden区)
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)