You are on page 1of 4

Rebuilding Indexes (RBIN)

Current State of the Index


Determining if the Index Needs to be Rebuilt
The Role of the INDEX_STATS View in Index Rebuilds
A Final Note on Rebuilding

Indexes provide a fast and efficient method of retrieving selected data from a table. By pointing to the
blocks that contain the selected data, the entire table does not have to read in order to extract the
required information. Most indexes in Oracle databases are built using the B-tree data structure. While Btree indexes in Oracle are always balanced, they do not clean up any free space after leaf entries have
been moved due to an UPDATE statement or removed due to a DELETE statement. Too many empty
leaf entries in an index can cause the index to be too high, which can cause poor performance.

Current State of the Index


In order to understand what must be done with the index, it is important to first get an idea of the current
state of the index. This can be accomplished by using the ANALYZE INDEX VALIDATE STRUCTURE
command.
Normally, the ANALYZE INDEX command creates either computed or estimated statistics for the index
that can be seen in the DBA_INDEXES view. Analyzing the index changes the optimizer's execution
plans for queries that potentially use that index. This action may produce unintentional side effects,
especially if the index has not previously been analyzed. The VALIDATE STRUCTURE command can be
safely executed without affecting the optimizer. The VALIDATE STRUCTURE command populates the
SYS.INDEX_STATS table only. The SYS.INDEX_STATS table can be accessed with the public synonym
INDEX_STATS. The INDEX_STATS table will only hold validation information for one index at a time.
Query this table before validating the structure of the next index.
Below is an example of ANALYZE INDEX VALIDATE STRUCTURE and sample output from
INDEX_STATS:
SQL> ANALYZE INDEX shopping_basket_pk VALIDATE STRUCTURE;
Statement processed.
SQL> SELECT name,height,lf_rows,lf_blks,del_lf_rows,distinct_keys,used_space
FROM INDEX_STATS;
NAME
HEIGHT
LF_ROWS
LF_BLKS DEL_LF_ROW DISTINCT_K USED_SPACE
-------------------- --------- ---------- ---------- ---------- ----------- ---------SHOPPING_BASKET_PK
2
1
3
1
1
65

65
1 row selected.

Determining if the Index Needs to be Rebuilt


The following index types can now be rebuilt and moved online:

Reverse key indexes facilitating updates of stale logical ROWID's


Function-based indexes
Key-compressed indexes on index-organized and hash tables
Secondary indexes of IOTs
The Role of the INDEX_STATS View in Index Rebuilds

Page 1 of 4

There are two rules of thumb to help determine if the index needs to be rebuilt. If it is determined that the
index needs to be rebuilt, this can easily be accomplished by the ALTER INDEX REBUILD command.
Although not necessarily recommended, this command could be executed during normal operating hours.
You can rebuild the index ONLINE, but this can consume extra resources. Rebuilding the index uses the
existing index as a basis. The biggest benefit is that the leaf entries do not have to be resorted. It is
already sorted in the existing index. The alternative is to drop and re-create the index. Creating an index
uses the base table as its data source that needs to put a lock on the table. The index is also unavailable
during creation. The data must already be sorted, which is the biggest contributor to the index creation
time.
First rule of thumb: If the index has height greater than four, rebuild the index. For most indexes, the
height of the index will be quite low, i.e. one or two. There have been examples of an index on a 3 millionrow table that had height three. An index with height greater than four may need to be rebuilt as this might
indicate a tree structure with too many deleted leaf entries. This can lead to unnecessary database block
reads of the index. It is helpful to know the data structure for the table and index. Most times, the index
height should be two or less, but there are exceptions.
Second rule of thumb: The deleted leaf rows should be less than 20% of the total number of leaf
rows. An excessive number of deleted leaf rows indicates that a high number of deletes or updates have
occurred to the index column(s). The index should be rebuilt to better balance the index entries in the
tree. The INDEX_STATS table can be queried to determine if there are excessive deleted leaf rows in
relation to the total number of leaf rows.
For example:
SQLWKS> ANALYZE INDEX item_basket_pk VALIDATE STRUCTURE;
Statement processed.
SQLWKS> SELECT name,height,lf_rows,del_lf_rows,(del_lf_rows/lf_rows)*100
ratio FROM INDEX_STATS;
NAME
HEIGHT
LF_ROWS
DEL_LF_ROW
RATIO
------------------ ---------- ---------- ----------- -----------ITEM_BASKET_PK
1
235
74
31.4893617

as

In this example, the ratio of deleted leaf rows to total leaf rows is clearly above 20%. This is a good
candidate for rebuilding. Let's rebuild the index and examine the results.
SQLWKS> ALTER INDEX item_basket_pk REBUILD;
Statement processed.
SQLWKS> ANALYZE INDEX item_basket_pk VALIDATE STRUCTURE;
Statement processed.
SQLWKS> SELECT name,height,lf_rows,del_lf_rows,(del_lf_rows/lf_rows)*100
ratio FROM INDEX_STATS;
NAME
HEIGHT
LF_ROWS
DEL_LF_ROW
------------------ ---------- ---------- -----------ITEM_BASKET_PK
1
161
0
1 row selected.

as

RATIO
-----0

The index is rebuilt and validated once again. Examining the INDEX_STATS table shows that the 74
deleted leaf rows were dropped from the index. Notice that the total number of leaf rows went from 235 to
161, which is a difference of 74 leaf rows. This index should provide better performance for the
application.

The Role of the INDEX_STATS View in Index Rebuilds

Page 2 of 4

Click here for a case study illustrating the rebuilding process


Click here for sample script indicating when an index needs to be rebuilt
Oracle's ANALYZE INDEX VALIDATE STRUCTURE command provides a nice way of check an index to
see if it is a candidate for rebuilding. This command does not affect the Oracle optimizer's execution plan
for queries that may use the index. The results in the INDEX_STATS are checked after issuing the
VALIDATE STRUCTURE command. If an index has excessive height (greater than four) or a high
number of deleted leaf rows (over 20% of the total), we rebuild the index.

The Role of the INDEX_STATS View in Index Rebuilds


The INDEX_STATS view by default has no rows. You populate this view by executing the analyze
index...validate structure command. Once you do this, the INDEX_STATS will supposedly have the
necessary data to guide your index rebuild decisions.
Benefits from the INDEX_STATs view
Once you have the view populated, you can use it to look at and compute a number of useful items of
information that can help you stay on top of indexing in your database.
The key columns you need to pay attention to are the following:

HEIGHT: Height of the index, which begins at 1 for root only index.
BLOCKS: Number of blocks allocated to the index.
LF_ROWS: Number of leaf row entries (includes deleted row entries).
DEL_LF_ROWS: Number of deleted leaf row entries not yet cleaned out.
USED_SPACE: Total space used within the index (includes deleted entries).
PCT_USED: Percentage of space used within the index (includes deleted entries).
This is derived by the following formula: (USED_SPACE/BTREE_SPACE)*100.
BTREE_SPACE: Total size of the index (includes deleted entries).

You can estimate the non-deleted rows in an index by subtracting the DEL_LF_ROWS value from the
LF_ROWS value. You can estimate the percentage of space used by the non-deleted rows of an indexed
by using the following formula: ((USED_SPACE - DEL_LF_ROWS_LEN)/BTREE_SPACE) * 100

A Final Note on Rebuilding


In many cases, rebuilding the index can actually cause performance problems. When you rebuild the
index, you remove any deleted leaf entries. If a subsequent INSERT or UPDATE operation needs to
modify a leaf block, and there is no room in that leaf block (because you removed that space in your
rebuild operation), the leaf block must split. A leaf block split is an expensive operation and will hinder
INSERT and UPDATE performance. Rebuilding indexes is an operation that is best suited for those
columns that do not have strictly increasing values. For instance, a table of EMPLOYEES has an
employee id (EMPID) for each employee. The EMPID value is generated from a sequence. We would
never reuse an employees id and every new employees id will always be greater than the previous
employees ids. New employees are only inserted on the right side of the tree. After employees leave the
company, the left side of the tree becomes full of empty leaf blocks that will never get used by new
employees. This is a perfect candidate for rebuilding the index. If you have a table of contacts and you
index the ZIPCODE column, then this index should probably never be rebuilt, even if you have matched
the guidelines given in this section. If you delete a contact that had zipcode 12345, then when you insert
a new contact with this same zipcode, it will use that deleted leaf entry slot. If you had rebuilt this index,
that empty leaf entry slot would not be there.
The Role of the INDEX_STATS View in Index Rebuilds

Page 3 of 4

Index_Stats Table

Column Name

Significance

OPT_CMPR_PCTSAVE

percentage storage saving expected from optimal


prefix compression

HEIGHT
BLOCKS
NAME
PARTITION_NAME
LF_ROWS
LF_BLKS
LF_ROWS_LEN
LF_BLK_LEN
BR_ROWS
BR_BLKS
BR_ROWS_LEN

height of the b-tree


blocks allocated to the segment
name of the index
name of the index partition,if partitioned
number of leaf rows (values in the index)
number of leaf blocks in the b-tree
sum of the lengths of all the leaf rows
useable space in a leaf block
number of branch rows
number of branch blocks in the b-tree
sum of the lengths of all the branch blocks in the btree

BR_BLK_LEN
DEL_LF_ROWS
DEL_LF_ROWS_LEN
DISTINCT_KEYS
MOST_REPEATED_KEY
BTREE_SPACE
USED_SPACE
PCT_USED

useable space in a branch block


number of deleted leaf rows in the index
total length of all deleted rows in the index
number of distinct keys in the index
how many times the most repeated key is repeated
total space currently allocated in the b-tree
total space that is currently being used in the b-tree
percent of space allocated in the b-tree that is being
used

ROWS_PER_KEY
BLKS_GETS_PER_ACCESS

average number of rows per distinct key


Expected number of consistent mode block gets per
row. This assumes that a row chosen at random from
the table is being searched for using the index

PRE_ROWS
PRE_ROWS_LEN
OPT_CMPR_COUNT

number of prefix rows (values in the index)


sum of lengths of all prefix rows
optimal prefix compression count for the index

The Role of the INDEX_STATS View in Index Rebuilds

Page 4 of 4

You might also like