Friday, 29 August 2014

Oracle to find over sized(fragmented) index whos size is greater than tablesize

To find over sized(fragmented index)

select si.owner,si.tablespace_name, i.index_name, t.table_name,
round(si.bytes/1024/1024,1) index_mb, round(st.bytes/1024/1024,1) table_mb,
round(si.bytes/st.bytes*100,1) pct_larger
from dba_segments si, dba_indexes i, dba_tables t, dba_segments st
where
si.owner = i.owner
and si.segment_name = i.index_name
and si.tablespace_name=i.tablespace_name
and si.segment_type = 'INDEX'
and i.table_owner = t.owner
and i.table_name = t.table_name
and t.owner = st.owner
and t.table_name = st.segment_name
and st.segment_type = 'TABLE'
and si.bytes > st.bytes
and si.bytes> 100*1024*1024 /* Larger than 100 MB */
and si.owner = '&Schema_name'
order by pct_larger desc


++To find all the index used by DB,Which might be candidate for online rebuild.
Note: I am not covering partition indexes.

SELECT idx.index_name, 
round(bytes/1024/1024),idx.TABLE_NAME,idx.status,PARTITIONED,DEGREE
  FROM dba_segments seg,
       dba_indexes  idx
 WHERE idx.table_owner = '&Schema_name'
   AND idx.owner       = seg.owner
   AND idx.index_name  = seg.segment_name
   and idx.index_name in (select object_name from sys.WRH$_SEG_STAT_OBJ where owner='&Schema_name' and object_type='INDEX'  and object_name not like 'SYS%')
and seg.segment_type <> 'TABLE PARTITION'  

and bytes> 100*1024*1024 /* Larger than 100 MB */

or with out schema name

SELECT idx.owner,idx.index_name,
round(bytes/1024/1024),idx.TABLE_NAME,idx.status,PARTITIONED,DEGREE
  FROM dba_segments seg,
       dba_indexes  idx
 WHERE
 idx.table_owner <> 'SYS'
   AND idx.owner       = seg.owner
   AND idx.index_name  = seg.segment_name
   and idx.index_name in (select object_name from sys.WRH$_SEG_STAT_OBJ where
   object_type='INDEX'  and object_name not like 'SYS%')
and seg.segment_type <> 'TABLE PARTITION'  and bytes> 100*1024*1024 /* Larger than 100 MB */

 

+Rebuild command script:
select 'ALTER INDEX ZWFCC11.' || idx.index_name || ' REBUILD ONLINE PARALLEL 8;'
FROM dba_segments seg,
        dba_indexes  idx
  WHERE idx.table_owner = 'ZWFCC11'
    AND idx.owner       = seg.owner
    AND idx.index_name  = seg.segment_name
    -- and tab.partitioned='NO'
    and idx.index_name in 
    (select object_name from sys.WRH$_SEG_STAT_OBJ where owner='&Schema_name' 
    and object_type='INDEX'  and object_name not like 'SYS%')
 and seg.segment_type <> 'TABLE PARTITION'  
and bytes> 100*1024*1024

order by TABLE_NAME

No comments: