oracle invisible index 的探索

os: centos 7.4
db: oracle 11.2.0.4

oracle 从 11g 开始提供 invisible index 索引,这对线上系统添加索引引起的性能异常提供了可控的方法。

准备表


-- drop table tmp_t0 purge;
create table tmp_t0
as
select *
from dba_objects
where 1=1
;


insert into tmp_t0
select *
from tmp_t0
;
insert into tmp_t0
select *
from tmp_t0
;
insert into tmp_t0
select *
from tmp_t0
;
commit;

创建索引

create index IND_TMP_T0_N1 on tmp_t0(object_id) online ;

alter index IND_TMP_T0_N1 visible;

alter index IND_TMP_T0_N1 invisible;

收集统计信息

BEGIN
    dbms_stats.gather_table_stats(
        ownname=> 'scott' ,
        tabname=> 'tmp_t0',
        --partname=> 'p1',
        estimate_percent=> 100 , 
        cascade=> TRUE,
        --method_opt=>'for all columns size 1 ',
        --method_opt=>'for all columns size repeat ',
        method_opt=>'for all indexed columns size skewonly ',
        no_invalidate=>FALSE,
        granularity=>'AUTO',
        degree=>2
    );
END ;

optimizer_use_invisible_indexes

optimizer_use_invisible_indexes 参数控制优化器是否使用 invisible 索引,默认为 false

SQL> show parameter optimizer_use_invisible_indexes;

NAME				     TYPE	 VALUE
------------------------------------ ----------- ------------------------------
optimizer_use_invisible_indexes      boolean	 FALSE

SQL> set lines 200;
SQL> set pages 200;
SQL> 
SQL> 
SQL> set autotrace traceonly;

SQL> alter session set optimizer_use_invisible_indexes = false;

SQL> select * 
  from TMP_T0 t
 where 1=1
   and t.object_id=442350
;

Execution Plan
----------------------------------------------------------
Plan hash value: 1652152861

----------------------------------------------------------------------------
| Id  | Operation	  | Name   | Rows  | Bytes | Cost (%CPU)| Time	   |
----------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |	   |	32 |  3168 |   137   (0)| 00:00:02 |
|*  1 |  TABLE ACCESS FULL| TMP_T0 |	32 |  3168 |   137   (0)| 00:00:02 |
----------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("T"."OBJECT_ID"=442350)
   

session 级别启用 invisible index,可以看到执行计划使用了 IND_TMP_T0_N1

SQL> alter session set optimizer_use_invisible_indexes = true;

SQL> select * 
  from TMP_T0 t
 where 1=1
   and t.object_id=442350
;


Execution Plan
----------------------------------------------------------
Plan hash value: 1276431902

---------------------------------------------------------------------------------------------
| Id  | Operation       | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |       |  32 |  3168 |  33   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| TMP_T0      |  32 |  3168 |  33   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN      | IND_TMP_T0_N1 |  32 |     |   1   (0)| 00:00:01 |
---------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("T"."OBJECT_ID"=442350)
   

能否在 sql 语句级通过 hint 控制?

SQL> alter session set optimizer_use_invisible_indexes = false;

SQL> select/*+ opt_param('optimizer_use_invisible_indexes', 'true') */ * 
  from TMP_T0 t
 where 1=1
   and t.object_id=442350
;


Execution Plan
----------------------------------------------------------
Plan hash value: 1652152861

----------------------------------------------------------------------------
| Id  | Operation	  | Name   | Rows  | Bytes | Cost (%CPU)| Time	   |
----------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |	   |	32 |  3168 |   137   (0)| 00:00:02 |
|*  1 |  TABLE ACCESS FULL| TMP_T0 |	32 |  3168 |   137   (0)| 00:00:02 |
----------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("T"."OBJECT_ID"=442350)

SQL> select/*+ opt_param('optimizer_use_invisible_indexes', 'true') index(t IND_TMP_T0_N1) */ * 
  from TMP_T0 t
 where 1=1
   and t.object_id=442350
;


Execution Plan
----------------------------------------------------------
Plan hash value: 1652152861

----------------------------------------------------------------------------
| Id  | Operation	  | Name   | Rows  | Bytes | Cost (%CPU)| Time	   |
----------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |	   |	32 |  3168 |   137   (0)| 00:00:02 |
|*  1 |  TABLE ACCESS FULL| TMP_T0 |	32 |  3168 |   137   (0)| 00:00:02 |
----------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("T"."OBJECT_ID"=442350)
   

看上去无法通过 hint 控制使用 invisible index,只能在 system 级别和 system 级别参数来启用禁用不可见索引。

你可能感兴趣的:(#,oracle,table,index,#,oracle,optimizer,statistics,oracle,invisible,visible)