Saturday, July 19, 2014

Estimate size of index using explain plan

Today i have learned cool way to define after index rebuilt what will the index size be ? This method , estimating index size is based on explain plan . Not only rebuild process , additionally creation of index is  involved .

Basically ,

1. create table tbl1 as select * from dba_objects;
2. insert into tbl1 select * from tbl1 -- 2 times
3. commit;
3. call dbms_stats.gather_table_stats('USER','TBL1');
4. explain plan for create index user.tbl_idx1 on tbl1(object_name);
5. commit;

6. select * from table (dbms_xplan.display);

-----------------------------------------------------------------------------------
| Id  | Operation              | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------
|   0 | CREATE INDEX STATEMENT |          |   414K|  9707K|   441   (3)| 00:00:03 |
|   1 |  INDEX BUILD NON UNIQUE| TBL_IDX1 |       |       |            |          |
|   2 |   SORT CREATE INDEX    |          |   414K|  9707K|            |          |
|   3 |    TABLE ACCESS FULL   | TBL1     |   414K|  9707K|   334   (3)| 00:00:02 |
-----------------------------------------------------------------------------------

Note
-----
   - estimated index size: 16M bytes



6. create index user.tbl_idx1 on tbl1(object_name);

7. select bytes/1024 from dba_segments where segment_name='TBL_IDX1'

Size : 16384K

As a result , actual size and estimate size are so close . 

CArlos Sierra has a great article and script about this method which can be applied to whole system , schema ,table or single index . Object create DDL is used with explain plan statement to detect approximate size like this,

declare
  v_ddl clob;
begin

  select replace(dbms_metadata.get_ddl(object_type => 'INDEX',name => 'TBL_IDX1'),chr(10),' ') into v_ddl   FROM DUAL;

  execute immediate 'explain plan for '||v_ddl;
  commit;

end ;

After script execution,below sql gives segment size and estimated size

select object_name,object_owner,info estimatedSize,ds.BYTES segmentSize
  from (select p.object_name,p.object_owner,extractvalue(value(d), '/info/@type') type,
               extractvalue(value(d), '/info') info
          from plan_table p,
               table(xmlsequence(extract(xmltype(p.other_xml), '/*/info'))) d
         where p.other_xml is not null)X,dba_segments ds
 where type = 'index_size'
   and ds.owner=X.object_owner
   and ds.segment_name=X.object_name


OBJECT_NAME    OBJECT_OWNER    ESTIMATEDSIZE    SEGMENTSIZE
TBL_IDX1           USER                     16777216    16777216


This post was based on below blog posts

http://carlos-sierra.net/2014/07/18/free-script-to-very-quickly-and-cheaply-estimate-the-size-of-an-index-if-it-were-to-be-rebuilt/

http://richardfoote.wordpress.com/2014/04/24/estimate-index-size-with-explain-plan-i-cant-explain/

No comments:

Post a Comment