Oracle'daki bir tabloda dizinler tarafından tüketilen gerçek alanı nasıl bulabilirim?


11

Oracle 10g bir tablo üzerinde dizinler tarafından tüketilen gerçek alanı bulmak istiyorum. İleride kullanmak üzere kehanetin ayırdığı alanı dahil etmek istemiyorum. (Kehanet yükü dikkate alınmamalıdır.) Ben kullanılan baytları tahsis edilen baytları değil istiyorum.

İlerlememe yardımcı olabilir misiniz?

Ayrıca, bir tabloda uzun bir alanın gerçek boyutunu bulmanın bir yolu var.

PS: vsize () ve dbms_lob.getlength () çalışmıyor.


Bu iki yöntemin sizin için neden işe yaramadığını paylaşabilir misiniz?
jcolebrand

1
İkinci sorunuzu ayrıca sormalısınız.
Leigh Riffel

@ İyi puan. Kullanıcının taşındığını fark edip etmediğini ve burada yanıt almak için tüm adımları uygulayıp uygulamadığını görelim. Onların adına parmaklarımı geçiyorum.
jcolebrand

Yanıtlar:


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

size her bir dizin tarafından gerçekten tüketilen alan miktarını gösterir. Tam olarak ne tür bir ek yük oluşturmaya çalıştığınızı ve "kullanılmış" ve "tahsis edilmiş" öğeleri bir dizin bağlamında nasıl ayırt ettiğinizi tam olarak bilmiyorum. Dizindeki boş alanı hesaba katmak istiyorsanız, dizinde kaç tane boş blok bulunduğunu belirlemek için DBMS_SPACE.SPACE_USAGE yordamını kullanabilirsiniz .


2
Ben OP sorgu ne döner (ve sonra {otomatik} küçültmek sonra a değil ) olarak dizinde giriş sayısı ile değişecek kullanılan boyutu aksine tahsis anlıyor inanıyorum . delete <<name of table>>
René Nyffenegger

2
Bu komut DBA tablolarına erişmeden mümkündür: 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 BY idx.index_name
Richard Dingwall

@RichardDingwall - Dizinin sahibi olan Oracle kullanıcısı olarak oturum açtığınızı varsayarsak, bu işe yarayacaktır. Ne kadar alan kullanıldığına ilgi duyan bir DBA iseniz, genellikle tabloya sahip olandan başka bir kullanıcı olarak oturum açarsınız.
Justin Cave

6

Endeksin tahsis edilen ve kullanılan boyutunu (anladığınız şey olduğuna inandığım) ölçmek için, muhtemelen 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;
/

Bu yordam, * TQ84_SIZE_IX * adlı bir dizinin ayrılan ve kullanılan boyutunu ölçer. Tamlık uğruna, bildirdiği gibi bayt sayısını da ekledim user_segments.

Şimdi, bu prosedür eylemde görülebilir:

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;

Dizine bir giriş yapılarak aşağıdaki rakamlar döndürülür:

Space Used:      1078
Space Allocated: 65536
Segment:         65536

Dizini doldurma ...

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

... ve figürleri tekrar almak ...

exec tq84_index_size_proc;

... raporlar:

Space Used:      25579796
Space Allocated: 32505856
Segment:         32505856

Ardından, dizin "boşaltılırsa":

delete from tq84_size;
commit;
exec tq84_index_size_proc;

gösteriyor:

Space Used:      4052714
Space Allocated: 32505856
Segment:         32505856

bu, kullanılan boyutta ayrılan boyutun küçülmediğini gösterir.


2

Birisi buraya uzun bir alanın boyutunu bulmanın bir yolunu arıyorsa, aşağıda bunu yapmanın bir yolu var. Soru ayrılırsa bu cevabı kaldıracağım.

Örnek veri...

CREATE TABLE TLONG 
(
  C1 Number(3),
  C2 LONG 
);

INSERT INTO TLONG VALUES (1,'abcd');
INSERT INTO TLONG VALUES (2,'abc');
INSERT INTO TLONG VALUES (3,'ab');
INSERT INTO TLONG VALUES (4,'1234567890');

İşi yapmak için işlev ... (Üretim için bu bir paket içinde olmalıdır)

CREATE OR REPLACE FUNCTION GetLongLength (pKey Number) RETURN Number Is
   vLong Long;
BEGIN
   SELECT C2 INTO vLong FROM TLONG WHERE C1 = pKey;
   Return Length(vLong);
END;
/

SHOW ERRORS;

İşlevi test etme ...

SELECT rownum, GetLongLength(rownum) FROM dual CONNECT BY rownum<=4;

ROWNUM                 GETLONGLENGTH(ROWNUM)  
---------------------- ---------------------- 
1                      4                      
2                      3                      
3                      2                      
4                      10                   

0

Bir şemadaki tüm dizinler için alan kullanımını daha genel ve daha kolay hale getirmek için René Nyffenegger'in cevabını değiştirmek zorunda kaldım.

Başka birinin yararlı bulması durumunda, değiştirilen kodu burada paylaşacağımı düşündüm:

--==========================================
-- Show space usage by all indexes in schema
--==========================================
-- Required to show output in SQLDeveloper, which would supress it otherwise.
SET SERVEROUTPUT ON;
-- Calculates size for given index
CREATE OR REPLACE PROCEDURE calc_index_size(
    index_name IN VARCHAR2)
AS
  OBJECT_OWNER_in     VARCHAR2(30) := USER;
  OBJECT_NAME_in      VARCHAR2(30) := index_name;
  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:      ' || ROUND(SPACE_USED_out     /1024/1024, 2) || 'MB');
  dbms_output.put_line('Space Allocated: ' || ROUND(SPACE_ALLOCATED_out/1024/1024) || 'MB');
  dbms_output.put_line('Segment:         ' || ROUND(SUM_SEGMENT        /1024/1024) || 'MB');
END;
/
-- Shows index size for all indexes in a schema
DECLARE
BEGIN
  FOR user_indexes_sorted_by_size IN
  (SELECT idx.index_name,
    SUM(bytes)/1024/1024 AS "Size(MB)"
  FROM user_segments seg,
    user_indexes idx
  WHERE idx.index_name = seg.segment_name
  GROUP BY idx.index_name
  ORDER BY "Size(MB)" DESC
  )
  LOOP
    dbms_output.put_line( user_indexes_sorted_by_size.index_name );
    dbms_output.put_line( '-------------------------------------' );
    calc_index_size(user_indexes_sorted_by_size.index_name);
    dbms_output.put_line( '' );
  END LOOP;
END;
--==========================================
--==========================================
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.