it-swarm.asia

كيفية العثور على المساحة الفعلية التي تستهلكها الفهارس على طاولة في Oracle؟

أريد أن أجد المساحة الفعلية التي تستهلكها الفهارس على طاولة في Oracle 10g. لا أنوي تضمين المساحة التي تحتفظ بها Oracle للاستخدام في المستقبل. (لا ينبغي النظر في النفقات العامة من Oracle.) أريد وحدات البايت المستخدمة وليس وحدات البايت المخصصة.

هل يمكنك مساعدتي في المضي قدما؟

أيضا ، هل هناك طريقة للعثور على الحجم الفعلي لحقل طويل في الجدول.

PS: vsize () و dbms_lob.getlength () لا تعمل.

11
Egalitarian
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

سيظهر لك مقدار المساحة التي يستهلكها كل فهرس. لست واضحًا إذا كان هذا هو بالضبط نوع النفقات العامة التي تحاول حسابها وكيف تميز "المستخدم" و "المخصص" في سياق الفهرس. إذا كنت تريد حساب المساحة الحرة في الفهرس ، فيمكنك استخدام DBMS_SPACE.SPACE_USAGE لتحديد عدد الكتل الفارغة جزئيًا في الفهرس.

8
Justin Cave

لقياس (ما أعتقد أنه فهمك لـ) الحجم المخصص والمستخدم للفهرس ، ربما أستخدم 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;
/

يقيس هذا الإجراء الحجم المخصص والمستخدم لمؤشر يسمى * 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;

مع إدخال واحد في الفهرس ، يتم إرجاع الأرقام التالية:

Space Used:      1078
Space Allocated: 65536
Segment:         65536

ملء الفهرس ...

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

... والحصول على الأرقام مرة أخرى ...

exec tq84_index_size_proc;

... التقارير:

Space Used:      25579796
Space Allocated: 32505856
Segment:         32505856

ثم ، إذا تم "تفريغ" الفهرس:

delete from tq84_size;
commit;
exec tq84_index_size_proc;

يظهر:

Space Used:      4052714
Space Allocated: 32505856
Segment:         32505856

مما يدل على أن الحجم المخصص لا يتقلص بينما يتقلص الحجم المستخدم.

6
René Nyffenegger

إذا جاء شخص ما إلى هنا بحثًا عن طريقة للعثور على حجم حقل طويل ، فيما يلي طريقة للقيام بذلك. سأزيل هذه الإجابة إذا تم فصل السؤال.

بيانات نموذجية ...

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');

وظيفة للقيام بالعمل ... (للإنتاج يجب أن يكون هذا في عبوة)

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;

اختبار الوظيفة ...

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

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

اضطررت إلى تعديل إجابة René Nyffenegger لجعلها أكثر عمومية وأسهل لرؤية استخدام المساحة لجميع الفهارس في المخطط.

أعتقد أنني سأشارك الرمز المعدل هنا ، في حال وجد أي شخص آخر أنه مفيد:

--==========================================
-- 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;
--==========================================
--==========================================
0
Kshitiz Sharma