Skip to Main Content
  • Questions
  • How to calculate the actual size of a Index.

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Rajeshwaran.

Asked: January 22, 2009 - 10:20 am UTC

Last updated: January 23, 2009 - 8:54 am UTC

Version: 10.1.0

Viewed 50K+ times! This question is

You Asked

Tom,

 I have learnt from your site about "How to calculate the actual size of a table" 
 from http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:266215435203
 But i couldnot find " blocks, empty_blocks,avg_space, num_freelist_blocks " from user_indexes 
 data dictionary that you used for the table size calcualtion purpose. 
 can you please explain me with a small example How to calculate the actual size of a index

 Here is the script i used from my working.

 TIME in EXPLAIN Plan Vs Elapsed time in TKROF

CREATE TABLE T (x NUMBER,y VARCHAR2(4000));

INSERT INTO T(x,y) 
SELECT LEVEL, RPAD('*',LEVEL,'*')
FROM dual
CONNECT BY LEVEL <= 3999;

ALTER TABLE T ADD CONSTRAINT T_PK PRIMARY KEY(x);

Thanks,
Rajesh.

and Tom said...

you could analyze the index validate structure - and then you have the index stats view

but beware, this command (analyze index I validate structure) LOCKS the index.

You also have access to dbms_space (i have a little procedure wrapped around it to show information, search this site for show_space if you want it)


ops$tkyte%ORA10GR2> analyze index t_pk validate structure;

Index analyzed.

ops$tkyte%ORA10GR2> exec print_table( 'select * from index_stats' );
.HEIGHT                       : 2
.BLOCKS                       : 16
.NAME                         : T_PK
.PARTITION_NAME               :
.LF_ROWS                      : 3999
.LF_BLKS                      : 8
.LF_ROWS_LEN                  : 55848
.LF_BLK_LEN                   : 7996
.BR_ROWS                      : 7
.BR_BLKS                      : 1
.BR_ROWS_LEN                  : 70
.BR_BLK_LEN                   : 8028
.DEL_LF_ROWS                  : 0
.DEL_LF_ROWS_LEN              : 0
.DISTINCT_KEYS                : 3999
.MOST_REPEATED_KEY            : 1
.BTREE_SPACE                  : 71996
.USED_SPACE                   : 55918
.PCT_USED                     : 78
.ROWS_PER_KEY                 : 1
.BLKS_GETS_PER_ACCESS         : 3
.PRE_ROWS                     : 0
.PRE_ROWS_LEN                 : 0
.OPT_CMPR_COUNT               : 0
.OPT_CMPR_PCTSAVE             : 0
-----------------

PL/SQL procedure successfully completed.

ops$tkyte%ORA10GR2> exec show_space( 'T_PK', user, 'INDEX' );
Unformatted Blocks .....................               0
FS1 Blocks (0-25)  .....................               0
FS2 Blocks (25-50) .....................               1
FS3 Blocks (50-75) .....................               0
FS4 Blocks (75-100).....................               0
Full Blocks        .....................               8
Total Blocks............................              16
Total Bytes.............................         131,072
Total MBytes............................               0
Unused Blocks...........................               4
Unused Bytes............................          32,768
Last Used Ext FileId....................               4
Last Used Ext BlockId...................          31,849
Last Used Block.........................               4

PL/SQL procedure successfully completed.

Rating

  (2 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

How to calculate the actual size of a Index

Rajeshwaran Jeyabal, January 22, 2009 - 2:49 pm UTC


ops$tkyte%ORA10GR2> exec show_space( 'T_PK', user, 'INDEX' );
Unformatted Blocks ..................... 0
FS1 Blocks (0-25) ..................... 0
FS2 Blocks (25-50) ..................... 1
FS3 Blocks (50-75) ..................... 0
FS4 Blocks (75-100)..................... 0
Full Blocks ..................... 8
Total Blocks............................ 16
Total Bytes............................. 131,072
Total MBytes............................ 0
Unused Blocks........................... 4
Unused Bytes............................ 32,768
Last Used Ext FileId.................... 4
Last Used Ext BlockId................... 31,849
Last Used Block......................... 4

1) so looking at this Total Blocks = 16 & Unused Blocks = 4.
so my index size is about 12 blocks in size. Am i right Tom?

2) Also it is mentioned in the Oracle product documentation to use dbms_stats package to analyze tables & Index with dbms_stats.AUTO_SAMPLE_SIZE as estimate percent
instead of using ANALYZE table command right? they why you have used ANALYZE command in the above? Is it better than dbms_stats Tom?

Tom Kyte
January 22, 2009 - 3:54 pm UTC

1) well, technically, your index size is 16 blocks. 4 of them haven't been used at all yet.

2) I didn't gather statistics at all, I did nothing regarding statistics. Well, actually, since this was 10g and we created the index AFTER the table had data - the index has COMPUTE statistics on it already (create and rebuild compute statistics in 10g and above).

I validated the structure, I did nothing to gather any statistics.

Oracle 10g /11g compute statistics on INDEX

Suvendu, January 23, 2009 - 2:35 am UTC

Tom,

Reference to your above answer, below is my test case. Your comments to my understanding would be a great help.

Thanks,
Suvendu


bash-2.05$ sqlplus test/test

SQL*Plus: Release 11.1.0.6.0 - Production on Fri Jan 23 11:27:00 2009

Copyright (c) 1982, 2007, Oracle. All rights reserved.


Connected to:
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

TEST@dev11g>drop index IDX_OWNER_T;

Index dropped.

TEST@dev11g>create index idx_owner_t on t(owner);

Index created.

TEST@dev11g>select index_name, STATUS,NUM_ROWS,SAMPLE_SIZE,LAST_ANALYZED from user_indexes
2 where index_name='IDX_OWNER_T';

INDEX_NAME STATUS NUM_ROWS SAMPLE_SIZE LAST_ANAL
------------------------------ -------- ---------- ----------- ---------
IDX_OWNER_T VALID 487136 487136 23-JAN-09



1) So, the above output says, NO need to go for collecting the statistics after the creation. The creation of INDEX itself compute the statistics.
2) I understands, when NUM_ROWS and SAMPLE_SIZE points to the same values, the COMPUTE STATISTIC option being choosen instead of ESTIMATE statistics.


TEST@dev11g>l
1 select segment_name,bytes/1024/1024 from user_segments
2* where SEGMENT_NAME='IDX_OWNER_T'
TEST@dev11g>/

SEGMENT_NAME BYTES/1024/1024
-------------------- ---------------
IDX_OWNER_T 9


3) The above statement also says about the current size of the segment (index here).



TEST@dev11g>insert into t select * from t;

487136 rows created.

TEST@dev11g>insert /*+ append */ into t select * from t;

974272 rows created.

TEST@dev11g>commit;

Commit complete.

TEST@dev11g>alter index IDX_OWNER_T rebuild;

Index altered.

TEST@dev11g>select index_name, STATUS,NUM_ROWS,SAMPLE_SIZE,LAST_ANALYZED from user_indexes
2 where index_name='IDX_OWNER_T';

INDEX_NAME STATUS NUM_ROWS SAMPLE_SIZE LAST_ANAL
------------------------------ -------- ---------- ----------- ---------
IDX_OWNER_T VALID 1948544 1948544 23-JAN-09


4) REBUID option is also computes the statistics.


TEST@dev11g>select segment_name,bytes/1024/1024 from user_segments
2 where SEGMENT_NAME='IDX_OWNER_T';

SEGMENT_NAME BYTES/1024/1024
-------------------- ---------------
IDX_OWNER_T 36

TEST@dev11g>analyze index IDX_OWNER_T validate structure;

Index analyzed.

TEST@dev11g>select segment_name,bytes/1024/1024 from user_segments
2 where SEGMENT_NAME='IDX_OWNER_T';

SEGMENT_NAME BYTES/1024/1024
-------------------- ---------------
IDX_OWNER_T 36

TEST@dev11g> exit;

5) ANALYZE ...VALIDATE STRUCTURE, could be ignore in this test case as it's used to report the block curroption of a segment.

------

Tom Kyte
January 23, 2009 - 8:54 am UTC

1) as long as the table had data, yes, that is what I said.

2) as stated previously above, 10g and up does a compute during a create or rebuild, yes.

3) as stated previously above, yes.

4) as stated previously above, yes.

5) incorrect, it populates index_stats, as demonstrated, with additional information that is of interest in many cases. just be aware of the LOCKING issue.

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library