-- +----------------------------------------------------------------------------+ -- | Jeffrey M. Hunter | -- | jhunter@idevelopment.info | -- | www.idevelopment.info | -- |----------------------------------------------------------------------------| -- | Copyright (c) 1998-2012 Jeffrey M. Hunter. All rights reserved. | -- |----------------------------------------------------------------------------| -- | DATABASE : Oracle | -- | FILE : dba_index_schema_fragmentation_report.sql | -- | CLASS : Database Administration | -- | PURPOSE : Rebuilds an index to determine how fragmented it is. | -- | NOTE : As with any code, ensure to test this script in a development | -- | environment before attempting to run it in production. | -- +----------------------------------------------------------------------------+ PROMPT PROMPT +------------------------------------------------------------------------+ PROMPT | Index Fragmentation Report for a Specified Schema | PROMPT |------------------------------------------------------------------------| PROMPT | Rebuild the index when: | PROMPT | [*] deleted entries represent 20% or more of the current entries | PROMPT | [*] the index depth is more then 4 levels | PROMPT | | PROMPT | Possible candidate for bitmap index: | PROMPT | [*] when distinctiveness is more than 99% | PROMPT +------------------------------------------------------------------------+ PROMPT ACCEPT schema CHAR prompt 'Schema name (% allowed) : ' PROMPT SPOOL index_schema_fragmentation_report_&schema..lst SET SERVEROUTPUT ON SET ECHO OFF SET FEEDBACK 6 SET HEADING ON SET LINESIZE 180 SET PAGESIZE 50000 SET TERMOUT ON SET TIMING OFF SET TRIMOUT ON SET TRIMSPOOL ON SET VERIFY OFF DECLARE c_name INTEGER; ignore INTEGER; height index_stats.height%TYPE := 0; lf_rows index_stats.lf_rows%TYPE := 0; del_lf_rows index_stats.del_lf_rows%TYPE := 0; distinct_keys index_stats.distinct_keys%TYPE := 0; CURSOR c_indx IS SELECT owner, table_name, index_name FROM dba_indexes WHERE owner LIKE upper('&schema') AND owner NOT IN ('SYS','SYSTEM'); BEGIN dbms_output.enable (1000000); dbms_output.put_line ('Owner Index Name % Deleted Entries Blevel Distinctiveness'); dbms_output.put_line ('--------------- --------------------------------------- ----------------- ------ ---------------'); c_name := DBMS_SQL.OPEN_CURSOR; FOR r_indx in c_indx LOOP DBMS_SQL.PARSE(c_name,'analyze index ' || r_indx.owner || '.' || r_indx.index_name || ' validate structure', DBMS_SQL.NATIVE); ignore := DBMS_SQL.EXECUTE(c_name); SELECT height , DECODE (lf_rows, 0, 1, lf_rows) , del_lf_rows , DECODE (distinct_keys, 0, 1, distinct_keys) INTO height , lf_rows , del_lf_rows , distinct_keys FROM index_stats; -- -- Index is considered as candidate for rebuild when : -- - when deleted entries represent 20% or more of the current entries -- - when the index depth is more then 4 levels.(height starts counting from 1 so > 5) -- Index is (possible) candidate for a bitmap index when : -- - distinctiveness is more than 99% -- IF ( height > 5 ) OR ( (del_lf_rows/lf_rows) > 0.2 ) THEN dbms_output.put_line ( RPAD(r_indx.owner, 16, ' ') || RPAD(r_indx.index_name, 40, ' ') || LPAD(ROUND((del_lf_rows/lf_rows)*100,3),17,' ') || LPAD(height-1,7,' ') || LPAD(ROUND((lf_rows-distinct_keys)*100/lf_rows,3),16,' ')); END IF; END LOOP; DBMS_SQL.CLOSE_CURSOR(c_name); END; / SPOOL OFF PROMPT Report written to index_schema_fragmentation_report_&schema..lst PROMPT