什么是隐藏索引?
Invisible Index,顾名思义,就是不可见索引。隐藏索引不会被优化器使用,但是仍然需要维护。具体怎么隐藏,接下来我们进行学习。
使用场景
1)软删除
2)灰度发布
隐藏索引使用
创建测试表:
mysql> create table t3(id int(10) auto_increment primary key,name varchar(30),age int(4));
Query OK, 0 rows affected, 2 warnings (0.04 sec)
mysql> insert into t3(name,age) values('liuwen',23);
Query OK, 1 row affected (0.11 sec)
mysql> insert into t3(name,age) values('lihao',28);
Query OK, 1 row affected (0.01 sec)
mysql> insert into t3(name,age) values('sujie',25);
Query OK, 1 row affected (0.05 sec)
mysql> insert into t3(name,age) values('kangkang',30);
Query OK, 1 row affected (0.05 sec)
创建普通索引:
mysql> alter table t3 add index idx_name(name);
Query OK, 0 rows affected (0.09 sec)
创建隐藏索引:
mysql> alter table t3 add index idx_age(age) invisible;
Query OK, 0 rows affected (0.07 sec)
查看索引信息:
mysql> show index from t3 \G
*************************** 1. row ***************************
Table: t3
Non_unique: 0
Key_name: PRIMARY
Seq_in_index: 1
Column_name: id
Collation: A
Cardinality: 4
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
Expression: NULL
*************************** 2. row ***************************
Table: t3
Non_unique: 1
Key_name: idx_name
Seq_in_index: 1
Column_name: name
Collation: A
Cardinality: 4
Sub_part: NULL
Packed: NULL
Null: YES
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
Expression: NULL
*************************** 3. row ***************************
Table: t3
Non_unique: 1
Key_name: idx_age
Seq_in_index: 1
Column_name: age
Collation: A
Cardinality: 4
Sub_part: NULL
Packed: NULL
Null: YES
Index_type: BTREE
Comment:
Index_comment:
Visible: NO
Expression: NULL
3 rows in set (0.00 sec)
可以看到索引idx_age状态:Visible: NO
查看优化器对着两个索引的使用情况:
mysql> explain select * from t3 where name='kangkang' \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t3
partitions: NULL
type: ref
possible_keys: idx_name
key: idx_name
key_len: 123
ref: const
rows: 1
filtered: 100.00
Extra: NULL
1 row in set, 1 warning (0.00 sec)
mysql> explain select * from t3 where age=23 \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t3
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 4
filtered: 25.00
Extra: Using where
1 row in set, 1 warning (0.00 sec)
可以看到优化器并不能使用age字段上的索引idx_age。
打开优化器的开关,使隐藏索引可见:
mysql> select @@optimizer_switch \G
*************************** 1. row ***************************
@@optimizer_switch: index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on
1 row in set (0.00 sec)
可以看到一个关键信息:use_invisible_indexes=off
将会话级隐藏索引可见:
mysql> set session optimizer_switch='use_invisible_indexes=on';
Query OK, 0 rows affected (0.00 sec)
mysql> select @@optimizer_switch \G
*************************** 1. row ***************************
@@optimizer_switch: index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=on,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on
1 row in set (0.01 sec)
可以看到use_invisible_indexes=on
mysql> explain select * from t3 where age=23 \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t3
partitions: NULL
type: ref
possible_keys: idx_age
key: idx_age
key_len: 5
ref: const
rows: 1
filtered: 100.00
Extra: NULL
1 row in set, 1 warning (0.00 sec)
可以看到优化器可以使用age字段的索引idx_age了。
将普通索引设置为不可见:
mysql> alter table t3 alter index idx_name invisible;
Query OK, 0 rows affected (0.08 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> explain select * from t3 where name='kangkang' \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t3
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 4
filtered: 25.00
Extra: Using where
1 row in set, 1 warning (0.00 sec)
注意:主键索引不能设置为不可见。