3
我只想重建我的表索引,如果這樣做會釋放超過2GB的表空間。我如何確定重建索引可以釋放的表空間量?如何判斷將通過重建索引釋放的表空間量
我只想重建我的表索引,如果這樣做會釋放超過2GB的表空間。我如何確定重建索引可以釋放的表空間量?如何判斷將通過重建索引釋放的表空間量
您可以使用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