0
点赞
收藏
分享

微信扫一扫

MySQL8.0新特性之隐藏索引

兽怪海北 2022-08-30 阅读 71

2056735.jpg

什么是隐藏索引?

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)

注意:主键索引不能设置为不可见。

举报

相关推荐

0 条评论