Thursday, August 15, 2013

Index Rebuild Scripts

Some Important Links:

* http://jonathanlewis.wordpress.com/2007/09/16/index-rebuild/
* http://jonathanlewis.wordpress.com/2008/02/09/index-rebuild-10g/
* http://asktom.oracle.com/pls/asktom/f?p=100:11:3318814234016508::::P11_QUESTION_ID:2913600659112
* http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:35336203098853

Analyze INDEX <index name> validate structure;


this is session specific command. To check stats from index_stats view, you need to execute query from the same session where the above command is fired


index stats contains one row at a time.  It 
contains the outcome of the last validate structure. it goes away when you exit your session.

To check for index fragmentation


From Allappsdba blog:


 -- +------------------------------------------------------------------------------+
-- | PURPOSE  : To check for index fragmentation. As a rule of thumb if 10-15%  |
-- |            of the table data changes, then you should consider rebuilding the index  |
-- +-------------------------------------------------------------------------------+

ANALYZE INDEX &&index_name VALIDATE STRUCTURE; 

COL name         HEADING 'Index Name'          FORMAT a30 
COL del_lf_rows  HEADING 'Deleted|Leaf Rows'   FORMAT 99999999 
COL lf_rows_used HEADING 'Used|Leaf Rows'      FORMAT 99999999 
COL ibadness     HEADING '% Deleted|Leaf Rows' FORMAT 999.99999 

SELECT
    name
  , del_lf_rows
  , lf_rows - del_lf_rows lf_rows_used
  , TO_CHAR( del_lf_rows /(DECODE(lf_rows,0,0.01,lf_rows))*100,'999.99999') ibadness 
FROM   index_stats
/

prompt 
prompt Consider rebuilding any index if % of Deleted Leaf Rows is > 20%
prompt 

undefine index_name

============================================================================
From ORAFAQ
============================================================================

/* ************************************************************* */
/* Index Fragmentation Status (idsfrag.sql): */
/* */
/* This script will report the index fragmentation status */
/* for a schema. */
/* */
/* Note: - Do not run this scrip during peak processing hours!!! */
/* - This script will fail for locked tables. */
/* */
/* ************************************************************* */

prompt -- Drop and create temporary table to hold stats...
drop table my_index_stats
/
create table my_index_stats (
index_name varchar2(30),
height number(8),
del_lf_rows number(8),
distinct_keys number(8),
rows_per_key number(10,2),
blks_gets_per_access number(10,2)
)
/

prompt -- Save script which we will later use to populate the above table...
insert into my_index_stats
select NAME, HEIGHT, DEL_LF_ROWS, DISTINCT_KEYS, ROWS_PER_KEY,
BLKS_GETS_PER_ACCESS
from INDEX_STATS
-- Note this open line...

save /tmp/save_index_stats.sql replace

prompt
prompt -- Spool listing with validate commands...
col line1 newline
col line2 newline
col line3 newline
set pagesize 0
set echo off
set termout off
set trimspool on
set feed off
set linesize 200
spool /tmp/validate_indexes.sql
select 'prompt Process table '||owner||'.'||table_name||
', index '||index_name||'...' line1,
'validate index '||owner||'.'||index_name||';' line2,
'@/tmp/save_index_stats.sql' line3
from sys.dba_indexes where owner = 'SCOTT'
order by table_name, index_name
/
spool off
set termout on
set feed on

prompt
prompt -- Run script to validate indexes...
@/tmp/validate_indexes.sql

prompt -- Print nice report...
set pagesize 50000
set trimspool on
col height format 99999
col del_rows format 9999999
col rows/key format 999999.9
spool idxfrag.lst
select INDEX_NAME, HEIGHT, DEL_LF_ROWS "DEL_ROWS", DISTINCT_KEYS "DIST KEYS",
ROWS_PER_KEY "ROWS/KEY",
BLKS_GETS_PER_ACCESS "BLKS/ACCESS"
from MY_INDEX_STATS
/
spool off

-- Cleanup
drop table my_index_stats
/
! rm /tmp/validate_indexes.sql
! rm /tmp/save_index_stats.sql

prompt
prompt Report is in idxfrag.lst
prompt Done!!!
=============================================================================


Index Fragmentation / Rebuild







How to find index is fragmented?

First analyze index 



SQL>analyze index INDEX_NAME validate structure;

Then query INDEX_STATS view
1. If del_lf_rows/lf_rows is > .2 then index should be rebuild.
2. If height is 4 then index should be rebuild.
3. If lf_rows is lower than lf_blks then index should be rebuild.



SQL> column status format a10
SQL> select trunc((del_lf_rows/lf_rows)*100,2)||'%' "status" from index_stats;

status
----------
21.83%


How to remove index fragmentation?

There are two way to remove fragmentation.
1. index coalesce
2. index rebuild

What is difference between coalesce and rebuild please go through below link for more details
http://download.oracle.com/docs/cd/B14117_01/server.101/b10739/indexes.htm#g1007548



SQL> alter index IDX_OBJ_ID coalesce;

SQL> alter index IDX_OBJ_ID rebuild;

SQL> alter index IDX_OBJ_ID rebuild online;


Note: If any DML statement is running on base table then we have to use ONLINE keyword with index rebuilding.




SQL> analyze index idx_obj_id validate structure;

Index analyzed.

SQL> select trunc((del_lf_rows/lf_rows)*100,2)||'%' "status" from index_stats;

status
-------
40.85%

SQL> alter index IDX_OBJ_ID rebuild online;

Index altered.

SQL> analyze index idx_obj_id validate structure;

Index analyzed.

SQL> select trunc((del_lf_rows/lf_rows)*100,2)||'%' "status" from index_stats;

status
--------
0%


Note: Index rebuild when index is fragmented or it is needed, otherwise index rebuilding is myth for improve performance.

=============================================================================
select
‘exec analyzedb.reorg_a_table4(’||””||rtrim(t.table_owner)||””||’,’||””||
rtrim(t.table_name)||””||’);’,
t.table_owner||’.’||t.table_name name,
a.num_rows,
sum(t.inserts) ins,
sum(t.updates) upd,
sum(t.deletes) del,
sum(t.updates)+sum(t.inserts)+sum(t.deletes) tot_chgs,
to_char((sum(t.deletes)/(decode(a.num_rows,0,1,a.num_rows)))*100.0,’999999.99′) per_del,
round(((sum(t.updates)+sum(t.inserts)+sum(t.deletes))/(decode(a.num_rows,0,1,a.num_rows)) *100.0),2) per_chg
from analyzedb.table_modifications t,
all_tables a
where t.timestamp >= to_date(’&from_date’,’dd-mon-yyyy’) and
t.table_owner = a.owner and t.table_owner not in (’SYS’,’SYSTEM’) and
t.table_name=a.table_name
having (sum(t.deletes)/(decode(a.num_rows,0,1,a.num_rows)))*100.0 >=5
group by t.table_owner, t.table_name, a.num_rows
order by num_rows desc, t.table_owner, t.table_name;
=====================================================================

1 comment:

Unknown said...

Good work sir, Thanks for the proper explanation about BigData and Hadoop introduction . I found one of the good resource related to bigData and Hadoop . It is providing in-depth knowledge on bigData and Hadoop . which I am sharing a link with you where you can get more clear on BigData and Hadoop . To know more Just have a look at this link Hadoop an intro…. BigData