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 級別參數來啓用禁用不可見索引。

發佈了732 篇原創文章 · 獲贊 70 · 訪問量 51萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章