oracle - 如何判断通过重建索引将释放的表空间量

标签 oracle database-administration

如果重建表索引会释放超过 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

现在模拟一个“坏”索引。一个常见的误解是索引不会自动重新使用空间。真正的问题是,在删除每个条目之前,索引不会重新声明叶 block 的空间。此示例删除 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

关于oracle - 如何判断通过重建索引将释放的表空间量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17679033/

相关文章:

帐户名中的Mysql句点字符

oracle - ORA-01658 : unable to create INITIAL extent for segment in tablespace TS_DATA

postgresql - 如何列出所有事件 session 的所有准备好的陈述?

mysql - SUM 列值与 group by aggregate 处理空值

java - Oracle 11g dbms_java.start_jmx_agent 抛出异常

sql - 如何处理 pl/sql block 中的编译时异常?

database - Oracle 中用户和模式之间的区别?

linux - 甲骨文Linux前端

java - Oracle数据无法设置公历时间

oracle - 对于其他用户,如何隐藏表的 Oracle 对象所有者