Oracle permite ca indecșii să fie marcați ca invizibili. Indecșii invizibili sunt menținuți ca orice alt index, dar sunt ignorați de optimizator, cu excepția cazului în care parametrul OPTIMIZER_USE_INVISIBLE_INDEXES este setat la TRUE la nivel de instanță sau sesiune. Indecșii pot fi creați ca fiind invizibili folosind cuvântul cheie INVISIBLE, iar vizibilitatea lor poate fi comutată folosind comanda ALTER INDEX.
create index index_name on table_name(column_name) invisible; alter index index_name invisible; alter index index_name visible;
Indicii invizibili pot fi utili pentru procesele cu nevoi specifice de indexare, unde prezența indicilor poate afecta negativ alte zone funcționale. De asemenea, sunt utile pentru testarea impactului adăugării sau eliminării unui index.
Următorul script creează și populează un tabel, apoi creează un index invizibil pe acesta. create table tab1 as select level as id from dual connect by level <= 10000; create index ind1_id on tab1(id) invisible; exec dbms_stats.gather_table_stats(null, ‘tab1’, cascade=> true);
Starea curentă de vizibilitate a unui index este indicată de coloana VIZIBILITATE a vizualizărilor [DBA|ALL|USER]_INDEXES.
column index_name format a30 column visibility format a10 select index_name, visibility from user_indexes; INDEX_NAME VISIBILITY ------------------------------ ---------- IND1_ID INVISIBLE
O interogare care utilizează coloana indexată din clauza WHERE ignoră indexul și efectuează o scanare completă a tabelului.
select * from tab1 where id = 9999; select * from table(dbms_xplan.display_cursor); ---------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ---------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 7 (100)| | |* 1 | TABLE ACCESS FULL| TAB1 | 1 | 4 | 7 (0)| 00:00:01 | ---------------------------------------------------------------------------- Setarea parametrului OPTIMIZER_USE_INVISIBLE_INDEXES face ca indexul să fie disponibil pentru optimizator.
alter session set optimizer_use_invisible_indexes=true; select * from tab1 where id = 9998; select * from table(dbms_xplan.display_cursor); ------------------------------------------------------------------------------ | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | | | 1 (100)| | |* 1 | INDEX RANGE SCAN| IND1_ID | 1 | 4 | 1 (0)| 00:00:01 | ------------------------------------------------------------------------------
Dacă faceți indexul vizibil, acesta este încă disponibil pentru optimizator atunci când parametrul OPTIMIZER_USE_INVISIBLE_INDEXES este resetat.
alter session set optimizer_use_invisible_indexes=false; alter index ii_tab_id visible; select * from TAB1 where id = 9997; select * from table(dbms_xplan.display_cursor); ------------------------------------------------------------------------------ | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | | | 1 (100)| | |* 1 | INDEX RANGE SCAN| IND1_ID | 1 | 4 | 1 (0)| 00:00:01 | ------------------------------------------------------------------------------
Dacă faceți din nou indexul invizibil, acesta nu mai este disponibil pentru optimizator.
alter index ind1_id invisible; select * from tab1 where id = 9996; select * from table(dbms_xplan.display_cursor); ---------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ---------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 7 (100)| | |* 1 | TABLE ACCESS FULL| TAB1 | 1 | 4 | 7 (0)| 00:00:01 | ----------------------------------------------------------------------------[mai mult...]