Je veux trouver l'espace réel consommé par les index sur une table dans Oracle 10g. Je n'ai pas l'intention d'inclure l'espace réservé par Oracle pour une utilisation future. (La surcharge d'Oracle ne doit pas être prise en compte.) Je veux que les octets utilisés ne soient pas les octets alloués.
Pouvez-vous m'aider à aller de l'avant?
Existe-t-il également un moyen de trouver la taille réelle d'un champ long dans une table.
PS: vsize () et dbms_lob.getlength () ne fonctionnent pas.
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
vous montrera la quantité d'espace réellement consommée par chaque index. Je ne sais pas exactement si c'est exactement ce type de frais généraux que vous essayez de prendre en compte et comment vous distinguez "utilisé" et "alloué" dans le contexte d'un index. Si vous souhaitez prendre en compte l'espace libre dans l'index, vous pouvez utiliser la procédure DBMS_SPACE.SPACE_USAGE pour déterminer le nombre de blocs partiellement vides dans l'index.
Pour mesurer (ce que je crois que vous comprenez) la taille allouée et utilisée de l'index, j'utiliserais probablement 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;
/
Cette procédure mesure la taille allouée et utilisée d'un index nommé * TQ84_SIZE_IX *. Par souci d'exhaustivité, j'ai également ajouté le nombre d'octets rapporté par user_segments
.
Maintenant, cette procédure peut être vue en action:
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;
Avec une entrée dans l'index, les chiffres suivants sont renvoyés:
Space Used: 1078
Space Allocated: 65536
Segment: 65536
Remplir l'index ...
insert into tq84_size
select substr(object_name || object_type, 1, 40),
rownum
from dba_objects,
dba_types
where rownum < 500000;
commit;
... et retrouver les chiffres ...
exec tq84_index_size_proc;
...rapports:
Space Used: 25579796
Space Allocated: 32505856
Segment: 32505856
Ensuite, si l'index est "vidé":
delete from tq84_size;
commit;
exec tq84_index_size_proc;
ça montre:
Space Used: 4052714
Space Allocated: 32505856
Segment: 32505856
ce qui démontre que la taille allouée ne diminue pas alors que la taille utilisée le fait.
Si quelqu'un vient ici à la recherche d'un moyen de trouver la taille d'un long champ, voici un moyen de le faire. Je supprimerai cette réponse si la question est séparée.
Exemples de données ...
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');
Fonction pour faire le travail ... (Pour la production, cela devrait être dans un emballage)
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;
Testez la fonction ...
SELECT rownum, GetLongLength(rownum) FROM dual CONNECT BY rownum<=4;
ROWNUM GETLONGLENGTH(ROWNUM)
---------------------- ----------------------
1 4
2 3
3 2
4 10
J'ai dû modifier la réponse de René Nyffenegger pour la rendre plus générique et plus facile à voir l'utilisation de l'espace pour tous les index d'un schéma.
Je pensais partager le code modifié ici, au cas où quelqu'un d'autre le trouverait utile:
--==========================================
-- 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;
--==========================================
--==========================================