จะค้นหาพื้นที่จริงที่ดัชนีใช้อยู่บนตารางใน Oracle ได้อย่างไร


11

ฉันต้องการค้นหาพื้นที่จริงที่ถูกใช้โดยดัชนีบนโต๊ะใน oracle 10g ฉันไม่ต้องการรวมพื้นที่ที่สงวนไว้โดย oracle สำหรับการใช้งานในอนาคต (ไม่ควรพิจารณาค่าใช้จ่ายโดย oracle) ฉันต้องการไบต์ที่ใช้ไม่ใช่ไบต์ที่ปันส่วน

คุณช่วยฉันก้าวไปข้างหน้าได้ไหม?

นอกจากนี้ยังมีวิธีการหาขนาดที่แท้จริงของเขตข้อมูลยาวในตาราง

PS: vsize () และ dbms_lob.getlength () ไม่ทำงาน


คุณแบ่งปันได้ไหมว่าทำไมทั้งสองวิธีนี้จึงไม่ได้ผลสำหรับคุณ
jcolebrand

1
คุณควรถามคำถามที่สองแยกต่างหาก
Leigh Riffel

@ จุดที่ดีสูง มาดูกันว่าผู้ใช้รับรู้ว่าพวกเขาได้รับการโยกย้ายและทำตามขั้นตอนทั้งหมดเพื่อรับคำตอบที่นี่หรือไม่ ข้ามนิ้วของฉันในนามของพวกเขา
jcolebrand

ดูstackoverflow.com/a/16661034/603516เพิ่มเติม
Vadzim

คำตอบ:


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

จะแสดงจำนวนเนื้อที่ที่ใช้จริงโดยแต่ละดัชนี ฉันไม่ชัดเจนว่าเป็นค่าใช้จ่ายประเภทใดที่คุณกำลังพิจารณาและวิธีแยกแยะ "ใช้" และ "จัดสรร" ในบริบทของดัชนี หากคุณต้องการบัญชีพื้นที่ว่างในดัชนีคุณสามารถใช้ขั้นตอน DBMS_SPACE.SPACE_USAGEเพื่อกำหนดจำนวนบล็อกว่างเปล่าบางส่วนในดัชนี


2
ฉันเชื่อว่า OP เข้าใจว่าจัดสรรเป็นสิ่งที่แบบสอบถามของคุณส่งคืน (และไม่ได้ย่อขนาด {หลัง} โดยอัตโนมัติdelete <<name of table>>เมื่อเทียบกับขนาดที่ใช้ซึ่งจะแตกต่างกันไปตามจำนวนรายการในดัชนี
René Nyffenegger

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 BY idx.index_name
Richard Dingwall

@RichardDingwall - สมมติว่าคุณล็อกอินเป็นผู้ใช้ Oracle ที่เป็นเจ้าของดัชนีซึ่งจะทำงาน หากคุณเป็น DBA สนใจว่ามีการใช้พื้นที่เท่าใดโดยทั่วไปคุณจะเข้าสู่ระบบในฐานะผู้ใช้รายอื่นนอกเหนือจากที่เป็นเจ้าของตาราง
Justin Cave

6

ในการวัด (สิ่งที่ฉันเชื่อว่าคุณเข้าใจ) การจัดสรรและใช้ขนาดของดัชนีฉันอาจใช้ 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

ซึ่งแสดงให้เห็นว่าขนาดที่จัดสรรไม่หดตัวขณะที่ขนาดที่ใช้ทำ


2

ในกรณีที่มีใครบางคนมาที่นี่กำลังมองหาวิธีที่จะหาขนาดของสนามยาวด้านล่างเป็นวิธีที่จะทำ ฉันจะลบคำตอบนี้ถ้าคำถามถูกแยกออก

ข้อมูลตัวอย่าง ...

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                   

0

ฉันต้องแก้ไขคำตอบของ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;
--==========================================
--==========================================
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.