Oracle 10gのテーブルのインデックスによって消費されている実際のスペースを見つけたいです。オラクルが将来使用するために予約したスペースを含めるつもりはありません。(Oracleによるオーバーヘッドは考慮すべきではありません。)割り当てられたバイトではなく、使用されたバイトが欲しいです。
今後のお手伝いをお願いします。
また、テーブルの長いフィールドの実際のサイズを見つける方法はありますか。
PS:vsize()およびdbms_lob.getlength()は機能しません。
Oracle 10gのテーブルのインデックスによって消費されている実際のスペースを見つけたいです。オラクルが将来使用するために予約したスペースを含めるつもりはありません。(Oracleによるオーバーヘッドは考慮すべきではありません。)割り当てられたバイトではなく、使用されたバイトが欲しいです。
今後のお手伝いをお願いします。
また、テーブルの長いフィールドの実際のサイズを見つける方法はありますか。
PS:vsize()およびdbms_lob.getlength()は機能しません。
回答:
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プロシージャを使用して、索引に部分的に空のブロックがいくつあるかを判別できます。
delete <<name of table>>
)。
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
インデックスの割り当てられたサイズと使用されたサイズ(あなたが理解していると思います)を測定するには、おそらく 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;
インデックスに1つのエントリがあると、次の数値が返されます。
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
これは、割り当てられたサイズは縮小されないが、使用されたサイズは縮小されることを示しています。
誰かが長いフィールドのサイズを見つける方法を探してここに来た場合、以下はそれを行う方法です。質問が分かれている場合、この回答は削除します。
サンプルデータ...
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
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;
--==========================================
--==========================================