Oracle virtual Index – no segment index

Sometimes creation of an index can take a lot of time. It’s especially true for warehouses. In Oracle there is nice old trick to create definition of index in dictionary without allocating physical space. It can help you to quickly determine what columns should be indexed.

Virtual index – it’s dictionary definition of index which is not allocating physical space .

Let’s create test data

create table test_tbl
(id number);

begin
  for i in 1..10000
  loop
    insert into test_tbl values(i);
  end loop;
  commit;
end;
/

exec dbms_stats.gather_table_stats(user, 'TEST_TBL');

so our table has got 10k rows in it and following query is not optimal

explain plan for
select * from test_tbl
where id=5;

select * from table(dbms_xplan.display(format=>'BASIC'));

Plan hash value: 602094504

----------------------------------------------
| Id  | Operation                 | Name     |
----------------------------------------------
|   0 | SELECT STATEMENT          |          |
|   1 |  TABLE ACCESS STORAGE FULL| TEST_TBL |
----------------------------------------------

It makes sense to add index on column id. Let’s test it with virtual index first.

1. create virtual index on database – the index won’t consume storage space

create index test_tbl_idx on test_tbl(id) nosegment;

select object_name, object_type 
from user_objects 
where object_name='TEST_TBL_IDX';

OBJECT_NAME         OBJECT_TYPE 
------------------- ------------
TEST_TBL_IDX        INDEX

select * 
from user_segments 
where segment_name='TEST_TBL_IDX';

no rows selected

2. change session settings to consider virtual index in explain plan

alter session set "_use_nosegment_indexes" = true;

3. check explain plan

explain plan for
select * from test_tbl
where id=5;

select * from table(dbms_xplan.display(format=>'BASIC'));

Plan hash value: 2543399553

-----------------------------------------
| Id  | Operation        | Name         |
-----------------------------------------
|   0 | SELECT STATEMENT |              |
|   1 |  INDEX RANGE SCAN| TEST_TBL_IDX |
-----------------------------------------

4. If you are sure all is fine you can create real index

drop index test_tbl_idx;

create index test_tbl_idx on test_tbl(id);

Have a fun 🙂

Tomasz

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *