Làm thế nào để tìm không gian thực tế đang được sử dụng bởi các chỉ mục trên một bảng trong Oracle?


11

Tôi muốn tìm không gian thực tế đang được sử dụng bởi các chỉ mục trên một bảng trong orory 10g. Tôi không có ý định bao gồm không gian dành cho nhà tiên tri để sử dụng trong tương lai. (Không nên xem xét chi phí của oracle.) Tôi muốn các byte được sử dụng không phải là các byte được phân bổ.

Bạn có thể giúp tôi đi trước?

Ngoài ra, có một cách để tìm kích thước thực tế của một trường dài trong bảng.

PS: vsize () và dbms_lob.getlength () không hoạt động.


Bạn có thể chia sẻ lý do tại sao hai phương pháp đó không hiệu quả với bạn?
jcolebrand

1
Bạn nên hỏi riêng câu hỏi thứ hai của bạn.
Leigh Riffel

@ Điểm cao. Hãy xem liệu người dùng có nhận ra họ đã được di chuyển hay không và thực hiện tất cả các bước để được trả lời tại đây. Băng qua ngón tay của tôi thay mặt họ.
jcolebrand

Câu trả lời:


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

sẽ cho bạn thấy lượng không gian thực sự được tiêu thụ bởi mỗi chỉ số. Tôi không rõ chính xác đó là loại chi phí nào bạn đang cố gắng tính toán và cách bạn phân biệt "được sử dụng" và "được phân bổ" trong bối cảnh của một chỉ mục. Nếu bạn muốn chiếm không gian trống trong chỉ mục, bạn có thể sử dụng thủ tục DBMSinksACE.SPACE_USAGE để xác định có bao nhiêu khối trống một phần trong chỉ mục.


2
Tôi tin rằng OP hiểu được phân bổ là những gì truy vấn của bạn trả về (và điều đó không {tự động} co lại sau a delete <<name of table>>) trái ngược với kích thước được sử dụng sẽ thay đổi theo số lượng mục nhập trong chỉ mục.
René Nyffalanger

2
Lệnh này có thể thực hiện mà không cần truy cập vào các bảng 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 - Giả sử rằng bạn đã đăng nhập với tư cách là người dùng Oracle sở hữu chỉ mục, điều đó sẽ hoạt động. Tuy nhiên, nếu bạn là một DBA quan tâm đến việc sử dụng bao nhiêu dung lượng, bạn thường sẽ đăng nhập với tư cách người dùng khác với người dùng sở hữu bảng.
Hang Justin

6

Để đo lường (những gì tôi tin là sự hiểu biết của bạn về) kích thước được phân bổ và sử dụng của chỉ mục, có lẽ tôi nên sử dụng 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;
/

Quy trình này đo kích thước được phân bổ và sử dụng của một chỉ mục có tên * TQ84_SIZE_IX *. Để hoàn thiện hơn, tôi cũng đã thêm số byte như được báo cáo bởi user_segments.

Bây giờ, thủ tục này có thể được nhìn thấy trong hành động:

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;

Với một mục trong chỉ mục, các số liệu sau được trả về:

Space Used:      1078
Space Allocated: 65536
Segment:         65536

Làm đầy chỉ số ...

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

... và lấy lại số liệu ...

exec tq84_index_size_proc;

...báo cáo:

Space Used:      25579796
Space Allocated: 32505856
Segment:         32505856

Sau đó, nếu chỉ mục bị "làm trống":

delete from tq84_size;
commit;
exec tq84_index_size_proc;

nó cho thấy:

Space Used:      4052714
Space Allocated: 32505856
Segment:         32505856

chứng tỏ rằng kích thước được phân bổ không co lại trong khi kích thước được sử dụng.


2

Trong trường hợp ai đó đến đây tìm cách để tìm kích thước của một trường dài, dưới đây là một cách để làm điều đó. Tôi sẽ loại bỏ câu trả lời này nếu câu hỏi được tách ra.

Dữ liệu mẫu...

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

Chức năng thực hiện công việc ... (Để sản xuất, phần này phải có trong một gói)

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;

Kiểm tra chức năng ...

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

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

0

Tôi đã phải sửa đổi câu trả lời của René Nyffalanger để làm cho nó chung chung hơn và dễ dàng hơn để xem việc sử dụng không gian cho tất cả các chỉ mục trong một lược đồ.

Tôi nghĩ rằng tôi sẽ chia sẻ mã sửa đổi ở đây, trong trường hợp bất kỳ ai khác thấy nó hữu ích:

--==========================================
-- 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;
--==========================================
--==========================================
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.