http://clouddba.co/index-internal-oracle-using-simple-test-case/
Test Case:-
SQL> create table t1 as select * from dba_objects;
SQL>create index I1_T1 on t1(OBJECT_ID);
SQL> select OBJECT_NAME from t1 where object_id=30;
---------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 30 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID BATCHED| T1 | 1 | 30 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | I1_T1 | 1 | | 1 (0)| 00:00:01 |
---------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("OBJECT_ID"=30)
SQL>alter index I1_T1 invisible;
SQL> select OBJECT_NAME from t1 where object_id=30;
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 30 | 426 (1)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| T1 | 1 | 30 | 426 (1)| 00:00:01 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("OBJECT_ID"=30)
SQL> select /*+ use_invisible_indexes */ OBJECT_NAME from t1 where object_id=30;
---------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------- -------------
| 0 | SELECT STATEMENT | | 1 | 30 | 2 (0 )| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID BATCHED| T1 | 1 | 30 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | I1_T1 | 1 | | 1 (0)| 00:00:01 |
---------------------------------------------------------------------------------------------
2 - access("OBJECT_ID"=30)
SQL> select index_name,visibility from dba_indexes where index_name='I1_T1';
INDEX_NAME VISIBILIT
-------------------------------------------------------------------------------------------------------------------------------- ---------
I1_T1 INVISIBLE
Test case:-
SQL> create index I2_t1 on t1(object_type); SQL> alter index I2_t1 invisible; SQL> create bitmap index T3_BM_T1 on t1(object_type);

SQL> alter index I2_T1 invisible;
SQL> alter index T3_BM_T1 visible;
SQL> select object_name from t1 where object_type='PROCEDURE';
Execution Plan
------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2068 | 70312 | 281 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID BATCHED| T1 | 2068 | 70312 | 281 (0)| 00:00:01 |
| 2 | BITMAP CONVERSION TO ROWIDS | | | | | |
|* 3 | BITMAP INDEX SINGLE VALUE | T3_BM_T1 | | | | |
------------------------------------------------------------------------------------------------
3 - access("OBJECT_TYPE"='PROCEDURE')
SQL> alter index T3_BM_T1 invisible;
SQL> alter index I2_T1 visible;
SQL> select object_name from t1 where object_type='PROCEDURE';
---------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2068 | 70312 | 100 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID BATCHED| T1 | 2068 | 70312 | 100 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | I2_T1 | 2068 | | 6 (0)| 00:00:01 |
---------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("OBJECT_TYPE"='PROCEDURE')
Test case:-
SQL> create index I1_comp_t1 on t1(object_id,object_type);
SQL> drop index I2_T1;
SQL> drop index T3_BM_T1;
SQL> select object_name from t1 where object_id=30;
--------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 30 | 3 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID BATCHED| T1 | 1 | 30 | 3 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | I1_COMP_T1 | 1 | | 2 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
--------------------------------------------------
2 - access("OBJECT_ID"=30)
SQL> select object_name from t1 where object_type='SEQUENCE';
--------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2068 | 70312 | 372 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID BATCHED| T1 | 2068 | 70312 | 372 (0)| 00:00:01 |
|* 2 | INDEX SKIP SCAN | I1_COMP_T1 | 2068 | | 314 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("OBJECT_TYPE"='SEQUENCE')
filter("OBJECT_TYPE"='SEQUENCE')
Test case:-
SQL> create table t1(c1 number,c2 char(10),c3 date);
SQL> insert into t1 select rownum,'A',sysdate from dual connect by rownum<100000;
SQL> commit;
SQL> insert into t1 select rownum,'B',sysdate from dual connect by rownum<100
SQL> commit;
SQL> exec dbms_stats.gather_table_stats('C##TEST','T1');
PL/SQL procedure successfully completed.
SQL> set autotrace traceonly;
SQL> select c1 from t1 where c2='B';
Execution Plan
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 50049 | 782K| 137 (1)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| T1 | 50049 | 782K| 137 (1)| 00:00:01 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("C2"='B')
SQL> create index I1_T1 on T1(c1,c2);
Index created.
SQL> exec dbms_stats.gather_table_stats('C##TEST','T1');
PL/SQL procedure successfully completed.
SQL> select c1 from t1 where c2='B';
Execution Plan
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 98 | 1568 | 104 (1)| 00:00:01 |
|* 1 | INDEX FAST FULL SCAN| I1_T1 | 98 | 1568 | 104 (1)| 00:00:01 |
------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("C2"='B')
Bitmap indexes are not generally recommended for online transaction processing (OLTP) applications. B-tree indexes contain a ROWID with the indexed value. So, when updating tables and their indexes, Oracle has the ability to lock individual rows. Bitmap indexes are stored as compressed indexed values, which can contain a range of ROWIDs. Therefore, Oracle has to lock the entire range of the ROWIDs for a given value. This type of locking has the potential to cause deadlock situations with certain types of DML statements. SELECT statements are not affected by this locking problem. A solution to updates is to drop the index, do the updating in batch during off-hours, and then rebuild the bitmap index (you could also add/drop an index on a column(s) that makes the update faster possibly as well).
Bitmap indexes are not considered by the rule-based optimizer.
Performing an ALTER TABLE statement and modifying a column that has a bitmap index built on it invalidates the index.
Bitmap indexes do not contain any of the data from the column and cannot be used for any type of integrity checking.
Bitmap indexes cannot be declared as unique.
Bitmap indexes have a maximum length of 30 columns.
Test case:-
SQL> create table test_bitmap(c1 number,c2 char(100),c3 char(100));
SQL> insert into test_bitmap select rownum,'A','AA' from dual connect by rownum<1000000;
SQL> insert into test_bitmap select rownum,'B','BB' from dual connect by rownum<100000;
SQL> insert into test_bitmap select rownum,'C','CC' from dual connect by rownum<10000;
SQL> create bitmap index B_test_bitmap on test_bitmap(c2);
SQL> create bitmap index B_test_bitmap1 on test_bitmap(c3);
SQL> exec dbms_stats.gather_table_stats('C##TEST','TEST_BITMAP');
SQL> select c3 from test_bitmap where c2='B';
99999 rows selected.
Elapsed: 00:00:00.36
Execution Plan
----------------------------------------------------------
Plan hash value: 892894935
--------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 369K| 71M| 8665 (1)| 00:00:01 |
|* 1 | VIEW | index$_join$_001 | 369K| 71M| 8665 (1)| 00:00:01 |
|* 2 | HASH JOIN | | | | | |
| 3 | BITMAP CONVERSION TO ROWIDS| | 369K| 71M| 12 (0)| 00:00:01 |
|* 4 | BITMAP INDEX SINGLE VALUE | B_TEST_BITMAP | | | | |
| 5 | BITMAP CONVERSION TO ROWIDS| | 369K| 71M| 35 (0)| 00:00:01 |
| 6 | BITMAP INDEX FULL SCAN | B_TEST_BITMAP1 | | | | |
--------------------------------------------------------------------------------------------------
SQL> create index I_TEST_BITMAP on TEST_BITMAP(C2);
Index created.
Elapsed: 00:00:02.98
SQL> create index I_TEST_BITMAP1 on TEST_BITMAP(C3);
Index created.
Elapsed: 00:00:02.09
SQL> select c3 from test_bitmap where c2='B';
99999 rows selected.
Elapsed: 00:00:00.59
Execution Plan
------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 369K| 71M| 16675 (1)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID BATCHED| TEST_BITMAP | 369K| 71M| 16675 (1)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | I_TEST_BITMAP | 369K| | 5788 (1)| 00:00:01 |
-----------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("C2"='B')
Test case:-
SQL> CREATE TABLESPACE data_assm DATAFILE ‘+DATA’ SIZE 5G EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO;
SQL> CREATE TABLESPACE ind_assm DATAFILE ‘+DATA’ SIZE 5G EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO; SQL> create table t (id number, sometext varchar2(50),my_date date) tablespace data_assm;
SQL> create or replace procedure manyinserts as
begin
for i in 1..1000000 loop
insert into t values (id_seq.nextval, ‘DOES THIS CAUSE BUFFER BUSY WAITS?’,sysdate);
end loop;
commit;
end;
/
Procedure created.
SQL> create or replace procedure manysessions as
v_jobno number:=0;
begin
FOR i in 1..30 LOOP
dbms_job.submit(v_jobno,’manyinserts;’, sysdate);
END LOOP;
commit;
end;
/
Procedure created.
SQL> create index i_t on t(id) tablespace ind_assm;
Index created.
SQL>exec manysessions; (This will start load data with 30 multiple session)
SQL> exec dbms_stats.gather_table_stats(‘C##TEST’,’T’);
PL/SQL procedure successfully completed.
SQL> EXEC dbms_workload_repository.create_snapshot;
PL/SQL procedure successfully completed.

In AWR,top 10 wait event:-

SQL> CREATE TABLESPACE data_assm DATAFILE '+DATA' SIZE 5G EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO;
SQL> CREATE TABLESPACE ind_assm DATAFILE '+DATA' SIZE 5G EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO; SQL> create table t (id number, sometext varchar2(50),my_date date) tablespace data_assm;
SQL> create or replace procedure manyinserts as
begin
for i in 1..1000000 loop
insert into t values (id_seq.nextval, 'DOES THIS CAUSE BUFFER BUSY WAITS?',sysdate);
end loop;
commit;
end;
/
Procedure created.
SQL> create or replace procedure manysessions as
v_jobno number:=0;
begin
FOR i in 1..30 LOOP
dbms_job.submit(v_jobno,'manyinserts;', sysdate);
END LOOP;
commit;
end;
/
Procedure created.
SQL> create index i_t on t(id) reverse tablespace ind_assm;
Index created.
SQL>exec manysessions; (This will start load data with 30 multiple session)
SQL> exec dbms_stats.gather_table_stats('C##TEST','T');
PL/SQL procedure successfully completed.
SQL> EXEC dbms_workload_repository.create_snapshot;
PL/SQL procedure successfully completed.

AWR

Test case:-
create table test_func(c1 number,c2 date);
insert into test_func select rownum,sysdate from dual connect by rownum<100;
insert into test_func select rownum,sysdate-1 from dual connect by rownum<100;
insert into test_func select rownum,sysdate-2 from dual connect by rownum<100;
insert into test_func select rownum,sysdate-3 from dual connect by rownum<100;
insert into test_func select rownum,sysdate-4 from dual connect by rownum<100;
insert into test_func select rownum,sysdate-5 from dual connect by rownum<100;
insert into test_func select rownum,sysdate-6 from dual connect by rownum<100;
insert into test_func select rownum,sysdate-7 from dual connect by rownum<100;
insert into test_func select rownum,sysdate-8 from dual connect by rownum<100;
create index I_C2 on test_func(c2);
create index I_C2_FUNC on test_func(trunc(c2));
exec dbms_stats.gather_table_stats('C##TEST','TEST_FUNC');
SQL> select count(1) from test_func where trunc(c2)='03-FEB-18';
COUNT(1)
----------
100
Execution Plan
-------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 8 | 1 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 8 | | |
|* 2 | INDEX RANGE SCAN| I_C2_FUNC | 39 | 312 | 1 (0)| 00:00:01 |
-------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access(TRUNC(INTERNAL_FUNCTION("C2"))='03-FEB-18')
SQL> select count(1) from test_func where c2>'03-FEB-18' and c2<(to_date('03-FEB-18')+0.99999);
COUNT(1)
----------
100
Execution Plan
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 16 | 1 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 16 | | |
|* 2 | FILTER | | | | | |
|* 3 | INDEX RANGE SCAN| I_C2 | 29 | 464 | 1 (0)| 00:00:01 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter(TO_DATE('03-FEB-18')+.999988425925925925925925925925925925
9259>'03-FEB-18')
3 - access("C2">'03-FEB-18' AND "C2"<TO_DATE('03-FEB-18')+.9999884259
259259259259259259259259259259)
filter(TRUNC(INTERNAL_FUNCTION("C2"))>=TRUNC('03-FEB-18') AND
TRUNC(INTERNAL_FUNCTION("C2"))<=TRUNC(TO_DATE('03-FEB-18')+.999988425925
9259259259259259259259259259))
Test case:-
SQL> CREATE TABLE test_iot (c1 INTEGER PRIMARY KEY, c2 char(100),c3 date) ORGANIZATION INDEX INCLUDING c2 OVERFLOW;
SQL> insert into test_iot select rownum,'A',sysdate from dual connect by rownum<100000;
SQL> exec dbms_stats.gather_table_stats('C##TEST','TEST_IOT');
PL/SQL procedure successfully completed.
SQL> select count(1) from test_iot where c1=1;
COUNT(1)
----------
1
Execution Plan
----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 5 | 2 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 5 | | |
|* 2 | INDEX UNIQUE SCAN| SYS_IOT_TOP_92575 | 1 | 5 | 2 (0)| 00:00:01 |
----------------------------------------------------------------------------------------