Here is a little script to assist in determining candidates for index compression. It simple takes each index and generates a list of SQL's that show the cardinality of each combination of index columns. For example, for table X with an index on (A,B,C), it would generate:
select count(distinct(A)),
count(distinct(A||B)),
count(distinct(A||B||C)),
count(*)
from X
Its pretty basic, so obviously its your own responsibility to set things like the date format mask etc to ensure that the concatenation is valid.
set serverout on size 999999
declare
prev varchar2(255) := '*';
pt varchar2(255) := '*';
pto varchar2(255) := '*';
col_list varchar2(255);
begin
for i in (
select ic.TABLE_NAME,ic.TABLE_OWNER,ic.INDEX_NAME, ic.COLUMN_NAME,
ic.INDEX_OWNER||ic.INDEX_NAME conc
from dba_ind_columns ic
where (TABLE_NAME,TABLE_OWNER,INDEX_NAME) in
( select TABLE_NAME, TABLE_OWNER, INDEX_NAME
from dba_ind_columns
where INDEX_OWNER = '&OWNER'
and COLUMN_POSITION = 2
and TABLE_NAME not like 'DR$%' )
order by ic.TABLE_OWNER, ic.TABLE_NAME, ic.INDEX_NAME, ic.COLUMN_POSITION ) loop
if prev = i.conc then
col_list := col_list || '||' || i.COLUMN_NAME;
dbms_output.put_line(', count(distinct('||col_list||')) x');
else
col_list := i.COLUMN_NAME;
dbms_output.put_line(', count(*) from '||pto||'.'||pt||';');
dbms_output.put_line('select ');
dbms_output.put_line(' count(distinct('||col_list||')) x');
end if;
prev := i.conc; pt := i.TABLE_NAME; pto := i.TABLE_OWNER;
end loop;
dbms_output.put_line(' , count(*) from '||pto||'.'||pt||';');
end;
/