Segment reorganization

See How to manage space

Table reorganization
select b.*, decode(optimal, 0, 0, wasted*100/optimal) perc_wasted from (
  select a.*, effective-optimal wasted from (
    select dba_tables.owner, table_name, dba_tables.blocks*dba_tablespaces.block_size effective
    , num_rows*avg_row_len optimal
	, last_analyzed, dba_tables.blocks table_blocks
	, dba_tablespaces.tablespace_name, dba_tablespaces.min_extlen/dba_tablespaces.block_size extent_blocks
    from dba_tables, dba_segments, dba_tablespaces
    where dba_segments.owner = dba_tables.owner
    and dba_segments.segment_name = dba_tables.table_name
    and dba_tablespaces.tablespace_name = dba_segments.tablespace_name
  ) a
) b
where not owner in ('SYS', 'SYSTEM', 'OUTLN', 'PATROL', 'PERFSTAT')
and table_blocks>extent_blocks*20
order by perc_wasted desc

 

Indexes
--User activity must be stopped
create table s as select * from index_stats;

create table s_err (
owner varchar2(100), 
index_name varchar2(100),
err_msg varchar2(4000),
err_trace varchar2(4000))

declare
cursor c is
  select owner, index_name, 'analyze index '||owner||'.'||index_name||' validate structure' s
  from dba_indexes
  where owner not in ('SYS','SYSTEM', 'OUTLN', 'DBSNMP', 'PERFSTAT')
  order by owner, table_name;
  cr c%rowtype;
  backtrace varchar2(4000); --10g 
  mSQLERRM varchar2(4000);
begin
  open c;
  fetch c into cr;
  loop
    exit when c%notfound;
	begin
	  execute immediate cr.s;
	  insert into s (select * from index_stats);
	exception
	  when others then
	    mSQLERRM := SQLERRM;
	    --backtrace := DBMS_UTILITY.FORMAT_ERROR_BACKTRACE; --10g 
        insert into s_err(owner, index_name, err_msg, err_trace) 
	    values(cr.owner, cr.index_name, mSQLERRM , backtrace);
	end;
	commit;
	fetch c into cr;
  end loop;
  close c;
end;

select * from s_err;

select * from (
  select decode(lf_rows, 0, 0, del_lf_rows*100/lf_rows) perc_del_lf_rows, s.* from s
) where height > 3 or perc_del_lf_rows > 30
order by name;