2013-07-16 3 views
3

Я бы хотел только перестроить индексы таблицы, если это приведет к выпуску табличного пространства более 2 гб. Как определить количество табличного пространства, которое будет освобождено путем восстановления индексов?Как определить количество табличного пространства, которое было бы освобождено путем перестройки индексов

ответ

2

Вы можете использовать DBMS_SPACE.CREATE_INDEX_COST, чтобы оценить количество занимаемого места после того, как индекс перестроен. Вычитая это из DBA_SEGMENTS.BYTES, вы получите оценку сохраненного пространства.

В приведенном ниже примере показано, как DBMS_SPACE делает довольно точное предсказание экономии пространства при восстановлении необычно плохого индекса. Пакет требует сбора статистики, поэтому вы можете прочитать о потенциальных проблемах, вызванных сбором статистики от this слегка связанный ответ.

Сначала создайте таблицу и образцы данных и соберите статистику.

drop table test1 purge; 
create table test1(a number, b number, c number); 

insert /*+ append */ into test1 select level, level, level 
from dual connect by level <= 500000; 
commit; 

begin 
    dbms_stats.gather_table_stats(user, 'TEST1'); 
end; 
/

Это показывает, что DBMS_SPACE делает точный прогноз стоимости нового индекса.

declare 
    v_used_bytes number; 
    v_alloc_bytes number; 
begin 
    dbms_space.create_index_cost(
     ddl => 'create index test1_idx on test1(a, b, c)' 
     ,used_bytes => v_used_bytes 
     ,alloc_bytes => v_alloc_bytes 
    ); 
    dbms_output.put_line('Esimated Bytes: '|| 
     trim(to_char(v_alloc_bytes,'999,999,999'))); 
end; 
/

Esimated Bytes: 14,680,064 


create index test1_idx on test1(a, b, c); 
select trim(to_char(bytes, '999,999,999')) actual_bytes 
    from dba_segments where segment_name = 'TEST1_IDX'; 

ACTUAL_BYTES 
------------ 
15,728,640 

Теперь смоделируйте «плохой» индекс. Общим мифом является то, что индексы не автоматически повторно используют пространство. Реальная проблема заключается в том, что индексы не будут повторно требовать пространство для листового блока до тех пор, пока каждая запись не будет удалена. В этом примере удаляется 95% строк, но объем пространства тот же.

delete from test1 where mod(a, 20) <> 1; 
commit; 
select trim(to_char(bytes, '999,999,999')) actual_bytes 
    from dba_segments where segment_name = 'TEST1_IDX'; 

ACTUAL_BYTES 
------------ 
15,728,640 

Повторно собрать статистику, и теперь оценка очень похожа на фактический размер после перестройки.

begin 
    dbms_stats.gather_table_stats(user, 'TEST1'); 
end; 
/

declare 
    v_used_bytes number; 
    v_alloc_bytes number; 
begin 
    dbms_space.create_index_cost(
     ddl => 'create index test1_idx on test1(a, b, c)' 
     ,used_bytes => v_used_bytes 
     ,alloc_bytes => v_alloc_bytes 
    ); 
    dbms_output.put_line('Esimated Bytes: '|| 
     trim(to_char(v_alloc_bytes,'999,999,999'))); 
end; 
/

Esimated Bytes: 720,896 


alter index test1_idx rebuild; 
select trim(to_char(bytes, '999,999,999')) actual_bytes 
    from dba_segments where segment_name = 'TEST1_IDX'; 

ACTUAL_BYTES 
------------ 
851,968 

 Смежные вопросы

  • Нет связанных вопросов^_^