如何在 Oracle 中的表上找到索引占用的实际空间?

Ega*_*ian 12 oracle oracle-10g

我想找到 oracle 10g 中表上的索引消耗的实际空间。我不打算包括 oracle 保留的空间以供将来使用。(不应该考虑oracle 的开销。)我想要使用的字节而不是分配的字节。

你能帮我继续前进吗?

另外,有没有办法找到表中长字段的实际大小。

PS:vsize() 和 dbms_lob.getlength() 不起作用。

Jus*_*ave 8

SELECT idx.index_name, SUM(bytes)
  FROM dba_segments seg,
       dba_indexes  idx
 WHERE idx.table_owner = <<owner of table>>
   AND idx.table_name  = <<name of table>>
   AND idx.owner       = seg.owner
   AND idx.index_name  = seg.segment_name
 GROUP BY idx.index_name
Run Code Online (Sandbox Code Playgroud)

将显示每个索引实际消耗的空间量。我不清楚这是否正是您要考虑的开销类型以及如何在索引上下文中区分“已使用”和“已分配”。如果要考虑索引中的可用空间,可以使用DBMS_SPACE.SPACE_USAGE 过程来确定索引中有多少部分为空的块。

  • 我相信 OP 将 *allocated* 理解为您的查询返回的内容(并且在 `delete &lt;&lt;name of table&gt;&gt;` 后不会{自动}缩小),而不是 *used* 大小,它会随着索引中的条目数。 (2认同)
  • 无需访问 DBA 表即可执行此命令:`SELECT idx.index_name, SUM(bytes) FROM user_segments seg, user_indexes idx WHERE idx.table_name = 'EMERGE_REPORTING_DETAIL' AND idx.index_name = seg.segment_name GROUP_name idx.index. (2认同)

Ren*_*ger 7

为了衡量(我相信你对索引的分配和使用大小的理解),我可能会使用 dbms_space

create or replace procedure tq84_index_size_proc 
as

  OBJECT_OWNER_in         varchar2(30) :=  user;
  OBJECT_NAME_in          varchar2(30) := 'TQ84_SIZE_IX';
  OBJECT_TYPE_in          varchar2(30) := 'INDEX';
  SAMPLE_CONTROL_in       number       :=  null;
  SPACE_USED_out          number;
  SPACE_ALLOCATED_out     number;
  CHAIN_PCENT_out         number;

  SUM_SEGMENT             number;

begin

  dbms_space.object_space_usage (
    OBJECT_OWNER           => OBJECT_OWNER_in        ,
    OBJECT_NAME            => OBJECT_NAME_in         ,
    OBJECT_TYPE            => OBJECT_TYPE_in         ,
    SAMPLE_CONTROL         => SAMPLE_CONTROL_in      ,
    SPACE_USED             => SPACE_USED_out         ,
    SPACE_ALLOCATED        => SPACE_ALLOCATED_out    ,
    CHAIN_PCENT            => CHAIN_PCENT_out
  );

  select sum(bytes) into SUM_SEGMENT 
    from user_segments
   where segment_name = OBJECT_NAME_in;


  dbms_output.put_line('Space Used:      ' || SPACE_USED_out);
  dbms_output.put_line('Space Allocated: ' || SPACE_ALLOCATED_out);
  dbms_output.put_line('Segment:         ' || SUM_SEGMENT);

end;
/
Run Code Online (Sandbox Code Playgroud)

此过程测量名为 *TQ84_SIZE_IX* 的索引的已分配和已使用大小。为了完整起见,我还添加了user_segments.

现在,这个过程可以在行动中看到:

create table tq84_size (
  col_1 varchar2(40),
  col_2 number
);

create index tq84_size_ix on tq84_size(col_1);

insert into tq84_size values ('*', 0);
commit;
exec tq84_index_size_proc;
Run Code Online (Sandbox Code Playgroud)

索引中有一个条目时,将返回以下数字:

Space Used:      1078
Space Allocated: 65536
Segment:         65536
Run Code Online (Sandbox Code Playgroud)

填写索引...

insert into tq84_size 
select substr(object_name || object_type, 1, 40),
       rownum
  from dba_objects,
       dba_types
 where rownum < 500000;
commit;
Run Code Online (Sandbox Code Playgroud)

......并再次获得数字......

exec tq84_index_size_proc;
Run Code Online (Sandbox Code Playgroud)

...报道:

Space Used:      25579796
Space Allocated: 32505856
Segment:         32505856
Run Code Online (Sandbox Code Playgroud)

然后,如果索引被“清空”:

delete from tq84_size;
commit;
exec tq84_index_size_proc;
Run Code Online (Sandbox Code Playgroud)

表明:

Space Used:      4052714
Space Allocated: 32505856
Segment:         32505856
Run Code Online (Sandbox Code Playgroud)

这表明分配的大小不会缩小,而使用的大小会缩小。