Vue d’ensemble
Parmi les principaux types d’objets d’un schéma, seuls les tables et les index occupent de
l’espace de stockage en dehors de leur définition dans le dictionnaire.
Cet espace de stockage doit être planifié correctement pour éviter les erreurs liées au
manque d’espace ou les problèmes de performance.
Les tables et les index sont des segments ; le stockage est donc organisé en extensions,
piloté par la clause STORAGE et par les caractéristiques du tablespace. Par ailleurs,
l’organisation du stockage dans les blocs a de l’importance.
Il existe d’autres types d’objets qui occupent de l’espace de stockage, mais ces derniers
sortent du périmètre de cet ouvrage :
• Index B-tree : index classique qui sera étudié dans cet ouvrage.
• Index Bitmap : index dont le stockage est organisé différemment des index B-tree et
qui est plutôt destiné à l’indexation des colonnes à faible cardinalité dans un
environnement décisionnel (l’index bitmap est très coûteux en mise à jour).
• Index à clé inversée : index B-tree qui indexe non pas la valeur de la colonne mais
une valeur résultant de l’inversion des octets de la colonne (intéressant pour
l’indexation de colonnes qui sont insérées en ordre croissant et interrogées par
égalité).
• Index basé sur des fonctions : index B-tree qui indexe non pas la valeur de la
colonne mais le résultat de l’application d’une fonction SQL (UPPER, LOWER, etc.) à
la valeur de la colonne. Il est intéressant lorsque la colonne n’est pas interrogée
directement (colonne opérateur valeur) mais avec la fonction (fonction(colonne)
opérateur valeur).
1 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
Structure du bloc
L’en-tête du bloc contient l’adresse du bloc, le type de segment, un répertoire des tables,
un répertoire des lignes et des entrées pour les transactions. La taille de l’en-tête du bloc
est variable, de l’ordre de 100 octets à 200 octets. Le reste du bloc contient les données
(une à plusieurs lignes de la table) et de l’espace libre.
L’en-tête est stocké dans la partie haute du bloc et les données sont insérées à partir du
bas. L’en-tête est susceptible de grossir (vers le bas) en fonction de l’activité dans le
bloc ; il ne rétrécit jamais. Par exemple, si 100 lignes sont insérées dans le bloc, le
répertoire des lignes situé dans l’en-tête grossit ; si les lignes sont ensuite supprimées, le
répertoire des lignes ne rétrécit pas (l’espace est conservé et pourra être réutilisé si des
lignes sont de nouveaux insérées dans le bloc).
L’en-tête d’une ligne contient quelques informations sur la ligne (nombre de colonnes,
chaînage éventuel, verrou). La taille de l’en-tête de lignes est variable (3 octets
minimum). Ensuite, chaque colonne est stockée avec un en-tête de colonne (qui donne la
longueur de la colonne sur 1 à 3 octets) suivi de la valeur de la colonne.
2 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
La longueur totale d’une ligne dépend du nombre de colonnes et de la valeur stockée dans
chaque colonne, la longueur de la colonne dépendant du type de données.
Exemple :
Une valeur NULL occupe un octet en milieu de ligne et aucun en fin de ligne.
Les fonctions SQL VSIZE et DUMP appliquées à une valeur (colonne, résultat d’une
expression) permettent de connaître respectivement la taille en octets du stockage
interne de la valeur et la représentation interne de la valeur.
Ce qu’il faut retenir, c’est que le bloc ne contient pas que des données utiles ; il y a des données
de contrôle, de surcharge, utilisées en interne par Oracle. À titre d’exemple, une ligne
comprenant 3 colonnes stockant 30 octets de données utiles emploiera en moyenne 35 octets
d’espace dans le bloc et une ligne comprenant 15 colonnes stockant 145 octets de données utiles
emploiera en moyenne 160 octets d’espace dans le bloc.
Dans le cas de la gestion "manuelle", pour chaque segment, Oracle gère une liste de blocs
disponibles pour l’insertion de lignes (freelist). La disponibilité ou la non-disponibilité d’un
bloc pour l’insertion est contrôlée par deux paramètres de la définition de la table :
PCTFREE et PCTUSED.
Dans le cas de la gestion "automatique", pour chaque segment, Oracle utilise une bitmap
afin de connaître le taux de remplissage de chaque bloc alloué au segment et en déduire
ceux dans lesquels il peut insérer des données. Dans ce cas, le paramètre PCTUSED est
sans objet. La gestion automatique est apparue en version 9.
3 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
PCTFREE
La clause PCTFREE permet de ne pas remplir les blocs à 100 % et de conserver de l’espace
disponible à l’intérieur du bloc, pour les futures mises à jour des lignes stockées dans le
bloc. En effet, lorsqu’une ligne est modifiée, Oracle cherche à réaliser la modification en
conservant la ligne à l’intérieur du bloc où elle est stockée : cela ne pose pas de problème
si la longueur globale de la ligne diminue (remplacement de PIERRE par PAUL dans une
colonne) mais peut en poser si la ligne grossit (remplacement de PAUL par PIERRE dans une
colonne). Dans ce dernier cas, s’il n’y a pas suffisamment d’espace disponible à l’intérieur
du bloc, Oracle va déplacer la ligne dans un autre bloc avec des impacts négatifs sur les
performances que nous verrons dans la suite de cet ouvrage.
Gestion automatique
4 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
En gestion automatique, Oracle utilise une bitmap pour connaître le taux de remplissage
de chaque bloc alloué au segment : 0 % d’espace libre (plein), entre 0 et 25 % d’espace
libre, entre 25 et 50 % d’espace libre, entre 50 et 75 % d’espace libre, entre 75 et 100 %
d’espace libre.
Lors de l’insertion d’une nouvelle ligne, Oracle utilisera la bitmap pour déterminer dans
quel bloc il peut insérer la ligne.
Dans la suite de ce chapitre, nous considérerons que la gestion automatique est utilisée. Nous
n’évoquerons pas PCTUSED et ne donnerons aucun conseil sur sa valeur.
Depuis Oracle9i Release 2, il est possible de compresser les données dans les blocs des
tables.
Depuis la version 11, il est possible d’activer la compression pour toutes les opérations, y
compris les insertions ou modifications individuelles. Ce type de compression peut donc
aussi être utilisé dans une base transactionnelle. Cette fonctionnalité, intitulé OLTP Table
Compression, nécessite l’option Advanced Compression.
Oracle compresse les données au niveau du bloc en factorisant dans une table de
symboles, les valeurs répétées stockées dans le bloc. Un exemple est donné à la section
Réorganiser le stockage d’une table.
2. Le ROWID
Le ROWID est une colonne virtuelle présente dans chaque table qui donne l’adresse
physique de stockage de la ligne. Cette colonne virtuelle peut être interrogée comme les
autres colonnes de la table :
Le ROWID permet de localiser physiquement la ligne ; il est utilisé en interne par Oracle
dans les index. S’il est connu, c’est le moyen le plus rapide pour accéder à une ligne.
5 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
package DBMS_ROWID offre plusieurs fonctions qui permettent d’extraire les différentes
composantes du ROWID.
Utiliser le ROWID dans une application (dans les clauses WHERE des ordres SQL) se révèle
très intéressant du point de vue des performances : Oracle obtient directement l’adresse
physique de la ligne à lire ou modifier, sans devoir lire toute la table ni passer par un
index.
Le ROWID d’une ligne ne change jamais, tant que la ligne n’est pas supprimée. Modifier
une ligne ne change pas son ROWID puisque la ligne est, a priori, modifiée à l’intérieur du
bloc où elle a été insérée ; ce sera aussi le cas si la ligne est migrée vers un autre bloc par
manque d’espace disponible (ce qui n’est pas bénéfique comme nous le verrons ci-après).
3. Chaînage et migration
En règle générale, une ligne d’une table est stockée en totalité à l’intérieur d’un bloc.
Pour lire la ligne, Oracle n’a besoin de lire qu’un seul bloc.
Si la ligne est intrinsèquement trop grande pour tenir dans un seul bloc, Oracle la stocke
dans plusieurs blocs chaînés par des pointeurs : c’est le phénomène de chaînage d’une
ligne. Pour lire cette ligne, Oracle a alors besoin de lire plusieurs blocs.
Si une ligne grandit suite à une modification, et qu’il ne reste plus suffisamment d’espace
libre dans le bloc, Oracle déplace la ligne dans un autre bloc pointé par l’en-tête de la
ligne resté dans le bloc d’origine : c’est le phénomène de migration d’une ligne. Le ROWID
de la ligne modifiée et migrée n’a pas changé, mais pour lire cette ligne, Oracle a besoin
de lire deux blocs, ce qui dégrade les performances des accès par index. L’intérêt de cette
technique est qu’Oracle n’a pas besoin de modifier le ROWID de la ligne dans les index lors
d’une mise à jour de la ligne.
Le phénomène de migration peut (et même doit) être évité, en laissant suffisamment
d’espace disponible dans les blocs pour les mises à jour. Le paramètre PCTFREE sera donc
positionné avec soin sur les tables pour lesquelles la taille des lignes insérées est
sensiblement inférieure à la taille des lignes après modification(s).
Le stockage d’une table peut être spécifié lors de la création de la table, dans l’ordre SQL
CREATE TABLE.
Syntaxe simplifiée
6 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
Exemple :
Les clauses TABLESPACE et STORAGE ont déjà été présentées au chapitre Gestion des
tablespaces et des fichiers de données. N’oubliez pas que la clause STORAGE est traitée
différemment selon que le tablespace est géré par le dictionnaire ou localement. Dans un
tablespace géré localement, seule l’option INITIAL est utile.
La clause PCTUSED donne la valeur du PCTUSED (entre 0 et 99, 40 par défaut). Cette
clause est ignorée si la table est stockée dans un tablespace géré localement avec une
gestion automatique de l’espace dans les segments.
La clause COMPRESS permet de compresser les données dans les blocs. L’option
DIRECT_LOAD indique que les blocs sont compressés, uniquement lors des opérations de
chargement direct (création de la table à partir d’une sous-requête, reconstruction de la
table ou chargement par des insertions en chemin direct) ; c’est la valeur par défaut.
L’option ALL indique que les blocs sont compressés pour toutes les opérations (y compris
les insertions ou modifications individuelles). Par défaut, la table hérite de l’option
COMPRESS ou NOCOMPRESS, éventuellement définie au niveau du tablespace dans lequel
elle est stockée.
Syntaxe simplifiée
7 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
L’ordre SQL ALTER TABLE n’a pas d’effet rétroactif sur le stockage déjà alloué à la table.
Il n’est donc pas possible, de cette manière, de changer la table de tablespace, de
modifier l’espace initialement alloué à la table ou le remplissage ou la compression des
blocs déjà utilisés.
Les caractéristiques modifiées sont prises en compte uniquement pour les futures
opérations. Plus tard, nous étudierons la clause MOVE de l’ordre SQL ALTER TABLE qui
permet de reconstruire physiquement le stockage d’une table.
Si vous souhaitez contrôler plus précisément le stockage des tables (ou de certaines
tables), vous pouvez utiliser des tablespaces gérés localement avec une gestion uniforme
de la taille des extensions (EXTENT MANAGEMENT LOCAL UNIFORM) et/ou spécifier avec
soin l’option INITIAL de la clause STORAGE.
8 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
Le fait qu’une table soit stockée dans un grand nombre d’extensions ne pose pas de problème du
point de vue des performances.
Par ailleurs, il ne faut pas hésiter à dédier des tablespaces au stockage des tables
volumineuses.
Dans un tablespace géré localement avec une gestion automatique de l’espace dans les segments,
les extensions doivent avoir une taille d’au moins 5 blocs.
La méthode la plus simple (et la plus pragmatique) pour estimer la volumétrie d’une table
à une échéance donnée consiste à :
Cette méthode ne donne qu’une estimation, pas un résultat exact à l’octet près, car il y a
de nombreuses incertitudes :
Supposons par exemple que la table ADHERENT (schéma DIANE) ait été chargée avec
10 000 lignes et qu’elle doive en contenir 1 000 000 à une échéance de 2 ans. Nous
pouvons réaliser le calcul suivant :
Le jeu de données utilise 138 blocs, donc, par règle de trois, nous pouvons estimer que la
table utilisera 13 800 blocs dans deux ans.
9 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
En production, un calcul de ce genre peut être effectué à intervalles réguliers pour voir la
tendance et vérifier si les hypothèses de départ étaient bonnes.
c. Estimation de PCTFREE
Avec calcul
Sans calcul
Pour une table "statique" ou faisant uniquement l’objet d’insertions, mettre un PCTFREE
faible pour obtenir un bon remplissage des blocs (0 à 5). Pour une table faisant l’objet
d’insertion et de mises à jour, mettre un PCTFREE plus élevé pour éviter les phénomènes
de migration (10 à 50 en fonction du risque que les mises à jour fassent grossir plus ou
moins les lignes).
En version 9, Oracle a introduit une fonctionnalité permettant de mettre une table "sous
surveillance". Dans ce mode, Oracle trace le nombre approximatif d’ordres SQL INSERT,
UPDATE et DELETE exécutés sur la table.
En version 9, cette fonctionnalité devait être activée explicitement ; depuis la version 10,
les tables sont, par défaut, sous surveillance (sauf si le paramètre STATISTICS_LEVEL est
égal à BASIC, ce qui est déconseillé).
Ce mécanisme de surveillance peut aussi être utilisé pour analyser l’activité sur les tables
et identifier les tables les plus sollicitées en mise à jour ; ce sont les tables sur lesquelles
vous devez plus particulièrement porter votre attention en ce qui concerne le stockage
(réglage de PCTFREE notamment).
10 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
Les informations sur les tables surveillées peuvent être consultées dans la vue DBA_TAB_
MODIFICATIONS (et consœurs).
Les statistiques sur l’utilisation d’une table ne sont pas déversées en temps réel dans le
dictionnaire. Le délai annoncé est entre quelques secondes et plusieurs heures. La colonne
TIMESTAMP de la vue DBA_TAB_MODIFICATIONS permet de connaître la fraîcheur de
l’information.
Il faut bien noter que les statistiques de surveillance sont supprimées lors de la génération
des statistiques. Les statistiques de surveillance sont donc collectées et cumulées depuis
la dernière génération de statistiques sur la table (voir la colonne LAST_ANALYZED de la
vue DBA_TABLES).
Pour une bonne analyse, il est important de réaliser des relevés périodiques afin de voir
l’évolution de l’activité et identifier d’éventuelles périodes de pointes.
Pour chaque table (et plus généralement chaque segment), Oracle connaît le dernier bloc
utilisé par la table : c’est la high water mark (HWM - "ligne de plus hautes eaux").
La HWM augmente lors des insertions mais ne diminue pas lors des suppressions :
11 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
La HWM permet donc de connaître le nombre total maximum de blocs utilisés par la table
dans toute son existence, mais pas le nombre de blocs actuellement utilisés, ni leur
remplissage.
Pour obtenir des informations plus détaillées sur le stockage d’une table, vous pouvez
utiliser le package DBMS_SPACE. Ce dernier propose plusieurs procédures qui permettent
notamment de calculer des informations sur l’espace libre et l’espace utilisé à l’intérieur
d’un segment.
Par ailleurs, pour les besoins de l’optimiseur, Oracle calcule périodiquement des
statistiques sur les tables (et les index), à l’aide du package DBMS_STATS ; certaines de
ces statistiques donnent des informations relatives au stockage.
Pour obtenir des informations plus détaillées sur le stockage d’une table, vous pouvez
utiliser les statistiques de la table, générées par le package DBMS_STATS ou calculer des
informations à l’aide du package DBMS_SPACE.
b. Le package DBMS_SPACE
Le package DBMS_SPACE propose plusieurs procédures qui peuvent être utilisées pour
superviser le stockage d’une table (plus généralement d’un segment) :
FREE_BLOCKS : informations sur les blocs libres dans un segment dont l’espace est géré
manuellement.
SPACE_USAGE : informations sur l’occupation des blocs dans un segment dont l’espace est
géré automatiquement.
Exemple :
12 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
SQL> DECLARE
2 v_total_blocks NUMBER;
3 v_total_bytes NUMBER;
4 v_unused_blocks NUMBER;
5 v_unused_bytes NUMBER;
6 v_last_extent_file NUMBER;
7 v_last_extent_block NUMBER;
13 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
8 v_last_used_block NUMBER;
9 PROCEDURE p(v_texte VARCHAR2) IS
10 BEGIN
11 dbms_output.put_line(v_texte);
12 END;
13 BEGIN
14 dbms_space.unused_space (
15 segment_owner => ’DIANE’,
16 segment_name => ’ADHERENT’,
17 segment_type => ’TABLE’,
18 total_blocks => v_total_blocks,
19 total_bytes => v_total_bytes,
20 unused_blocks => v_unused_blocks,
21 unused_bytes => v_unused_bytes,
22 last_used_extent_file_id => v_last_extent_file,
23 last_used_extent_block_id => v_last_extent_block,
24 last_used_block => v_last_used_block
25 );
26 p(’Blocs :’);
27 p(’. Total = ’||v_total_blocks);
28 p(’. Inutilisés = ’||v_unused_blocks);
29 p(’. Utilisés = ’||(v_total_blocks-v_unused_blocks));
30 END;
31 /
Blocs :
. Total = 224
. Inutilisés = 7
. Utilisés = 217
Procédure PL/SQL terminée avec succès.
Sur cet exemple, nous voyons que la table ADHERENT a 224 blocs alloués. Sur ces 224
blocs, 217 sont utilisés (c’est la HWM) et 7 sont inutilisés (jamais aucun ligne insérée à
l’intérieur). Sur les blocs utilisés, il y en a 128 qui sont pleins, 40 qui ont entre 25 et 50%
d’espace libre, 4 qui ont entre 50 et 75% d’espace libres et 33 qui ont entre 75 et 100%
d’espace libre, soit un total de 205 blocs. Les 12 blocs manquants pour arriver à 217 sont
des blocs de bitmap utilisés pour la gestion automatique (ils ne sont pas comptabilisés par
la procédure SPACE_USAGE).
Exemple :
EXECUTE dbms_stats.gather_table_stats(’DIANE’,’ADHERENT’)
14 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
Au point Les statistiques et l’optimiseur Oracle, nous verrons que les statistiques sont
calculées automatiquement par Oracle à intervalles réguliers. En temps normal, il n’est
donc pas nécessaire d’utiliser cette procédure. Générer manuellement des statistiques
peut, par contre, s’avérer utile si vous venez de créer et de charger une table, ou après
une mise à jour massive des données d’une table (insertion, modification, suppression).
Historiquement, les statistiques peuvent aussi être calculées à l’aide des clauses COMPUTE ou
ESTIMATE de l’ordre SQL ANALYZE TABLE. Cette possibilité est maintenue pour des raisons de
compatibilité ascendante. Pour calculer les statistiques sur les tables et les index, il faut utiliser le
package DBMS_STATS (depuis Oracle8i).
Les statistiques d’une table peuvent être consultées dans la vueDBA_TABLES (et
"consœurs") :
SAMPLE_SIZE : Nombre de lignes dans l’échantillon utilisé pour le calcul des statistiques.
La valeur BLOCKS est toujours exacte, même si les statistiques ne sont pas calculées sur la totalité
de la table.
Exemple :
Nous retrouvons les 217 blocs utilisés, calculés à l’aide du package DBMS_SPACE.
15 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
Les problèmes possibles sur le stockage d’une table sont les suivants :
Il y a de l’espace inutilisé alloué à la table si le nombre de blocs occupés (sous la HWM) est
faible par rapport au nombre de blocs alloués, et si la table ne va plus grossir (ou peu).
Le nombre de blocs occupés est donné par la valeur de la colonne BLOCKS de la vue
DBA_TABLES (ou par un calcul à l’aide du package DBMS_SPACE) et le nombre de blocs
alloués par la valeur de la colonne BLOCKS de la vue DBA_SEGMENTS.
Exemple :
occupés alloués
---------- ----------
217 224
Ce premier problème n’a pas d’incidence sur les performances (les blocs au-delà de la
HWM ne sont jamais lus) ; il conduit juste à un gaspillage d’espace disque.
Pour les tables dont l’espace est géré automatiquement, le taux d’occupation moyen des
blocs peut être analysé à l’aide du résultat donné par la procédure SPACE_USAGE du
package DBMS_SPACE.
Exemple :
Blocs :
. Pleins = 71
. 0 à 25% d’espace libre = 0
. 25 à 50% d’espace libre = 38
. 50 à 75% d’espace libre = 31
. 75 à 100% d’espace libre = 65
. Non formatés =0
Dans cet exemple, nous voyons que la table a 71 blocs pleins, 38 blocs moyennement
remplis et 96 faiblement remplis.
16 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
Ce mauvais remplissage des blocs peut être lié à une valeur inadaptée de PCTFREE ou à
une suppression importante de données.
La clause LIST CHAINED ROWS de l’ordre SQL ANALYZE TABLE permet d’identifier les lignes
migrées ou chaînées.
Syntaxe
Exemple :
SQL> @?\rdbms\admin\utlchain.sql
Table créée.
17 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
Dans la table CHAINED_ROWS, l’analyse stocke le ROWID des lignes qui ont un problème de
chaînage ou de migration ; à l’aide d’une sous-requête, il est possible de lister les lignes
proprement dites. Les résultats s’accumulent dans la table ; lors d’une nouvelle analyse
d’une table préalablement analysée, il convient dont de supprimer de CHAINED_ROWS
l’ancien résultat ou d’utiliser la colonne ANALYZE_TIMESTAMP pour extraire le résultat.
Pour savoir s’il s’agit d’un problème de chaînage ou de migration, il faut interroger la
ligne. Si la ligne est plus courte que la taille du bloc, il s’agit d’un problème de migration
(la ligne pourrait tenir dans un bloc) ; si la ligne est plus longue que la taille du bloc, il
s’agit d’un problème de chaînage. La statistique AVG_ROW_LEN dans DBA_TABLES donne
une indication a priori ; si la longueur moyenne des lignes est assez largement inférieure à
la taille de bloc, il s’agit sûrement d’un problème de migration.
Déterminer à partir de quel pourcentage de lignes chaînées ou migrées il faut agir n’est
pas simple. Le pourcentage en soi n’est pas suffisant ; cela dépend aussi de l’activité qui
existe sur les lignes en question. S’il y a 90 % de lignes migrées ou chaînées mais que ces
lignes ne sont jamais interrogées, il n’y a pas de problème de performance ; à l’inverse,
s’il n’y a que 1 % de lignes migrées ou chaînées mais que ces lignes soient utilisées dans
toutes les requêtes, il risque d’y avoir un problème de performance.
Plusieurs techniques sont à notre disposition pour réorganiser le stockage d’une table :
Le tableau suivant résume les techniques envisageables (√) et indique lesquelles sont les
mieux adaptées (☺) à tel ou tel besoin :
18 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
Export/
DEALLOCATE Recréer SHRINK MOVE
Import
Libérer de l’espace au-dessus de
☺ √ √ √ √
la HWM
Améliorer le taux de
√ √ ☺ ☺
remplissage des blocs
Corriger un problème de
☺ √ ☺
migration
Réorganisation plus globale √ √ ☺
À l’exception de l’ordre SQL ALTER TABLE ... DEALLOCATE UNUSED, les techniques citées
peuvent a priori être utilisés indifféremment pour régler les différents
problèmes ; néanmoins, certaines techniques sont mieux adaptées que d’autres à tel ou
tel besoin.
Pour le reste, les ordres SQL ALTER TABLE ... MOVE (depuis la 8i) et ALTER TABLE ...
SHRINK SPACE (depuis la 10) sont a priori les bons outils pour "reconstruire" une table.
L’ordre SQL ALTER TABLE ... DEALLOCATE UNUSED permet de libérer l’espace d’une table
situé au-dessus de la HWM.
Syntaxe
Exemple :
Sans clause KEEP, la taille initiale de la table est préservée : l’ordre ne libérera pas
d’espace si la HWM est inférieure à la taille initiale de la table (valeur de la colonne
INITIAL_EXTENT de la vue DBA_SEGMENTS).
Avec la clause KEEP, l’espace spécifié est conservé (éventuellement aucun avec KEEP 0) et
la taille initiale de la table, éventuellement ajustée dans le dictionnaire de données.
Par ailleurs, lorsque la table est stockée dans un tablespace géré localement, avec une
gestion uniforme des extensions, Oracle ne libérera que des extensions entières ; une
extension ne peut pas être "coupée" en deux. Si la table est stockée dans un tablespace
géré localement, avec une gestion automatique des extensions, Oracle peut "couper" une
extension en tenant compte des règles internes qu’il applique sur la taille des extensions.
19 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
L’espace libéré est rendu disponible pour d’autres segments (vue DBA_FREE_SPACE).
Cet ordre ne peut pas être utilisé pour libérer de l’espace au-dessous de la HWM (espace potentiel
libre suite à des suppressions de lignes, par exemple).
Au préalable, il faudra sauvegarder les données dans une table de travail (ordre SQL
CREATE TABLE ... AS SELECT).
Cette méthode présente un inconvénient majeur : les objets dépendants sont supprimés
(triggers, contraintes, privilèges, index) ou invalidés (procédures stockées, vues). Il faut
donc bien penser à tout recréer avec la table.
Exemple :
La table étant recréée avec de bonnes clauses de stockage, cette variante peut être
utilisée pour réorganiser complètement le stockage de la table, améliorer le taux de
remplissage des blocs, résoudre un problème de migration. Par contre, il faut penser à
recréer tous les objets dépendants et remettre les droits. De plus, le traitement peut être
long sur une table volumineuse.
Une première variante possible consiste à ne pas supprimer la table mais à la tronquer
(ordre SQL TRUNCATE TABLE) ; dans ce cas, les objets dépendants sont préservés.
Exemple :
Cette variante offre moins de possibilités pour la réorganisation puisque la table n’est pas
recréée ; néanmoins, elle permet d’améliorer le taux de remplissage des blocs (de libérer
de l’espace sous la HWM) et de résoudre un problème de migration. La table n’étant pas
supprimée, il n’y a pas de difficulté avec les objets dépendants.
Par contre, il n’est pas possible de tronquer une table qui possède une contrainte de clé
primaire référencée par ailleurs ; il faut au préalable désactiver les contraintes de clé
étrangère concernées. De plus, lors de l’insertion, les contraintes d’intégrités sont
20 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
vérifiées et les triggers sont déclenchés, ce qui peut aussi poser des problèmes : là encore,
il convient de désactiver les contraintes et/ou les triggers qui posent des difficultés.
Une autre variante, utilisable pour corriger un problème de migration sur un petit nombre
de lignes, consiste à ne supprimer et recréer que les lignes fautives. La table n’étant pas
supprimée, il n’y a pas de problème avec les objets dépendants. Par contre, là encore,
cette méthode peut poser des difficultés avec les contraintes de clé étrangère et les
triggers.
Exemple :
Pour ces différentes variantes, les outils d’export/import peuvent être utilisés pour
sauvegarder les données puis les réinsérer.
Dans la pratique, aucune de ces différentes variantes n’est vraiment simple à mettre en
œuvre. De plus, avec les deux premières variantes, la table n’est pas disponible pendant
la réorganisation.
L’ordre SQL ALTER TABLE ... SHRINK SPACE permet de compacter les lignes d’une table,
mais uniquement pour une table stockée dans un tablespace géré localement avec une
gestion automatique de l’espace dans les segments. Par défaut, Oracle compacte aussi le
segment, ajuste la HWM et libère l’espace ainsi récupéré.
Syntaxe
Avec l’option COMPACT, Oracle se contente de compacter les lignes, mais sans ajuster
la HWM ni libérer d’espace. L’exécution ultérieure d’un autre ordre SQL ALTER TABLE ...
SHRINK SPACE permettra de terminer l’opération.
L’option CASCADE permet de réaliser la même opération sur les segments dépendants de
la table, notamment les index.
Cette opération nécessite un déplacement des lignes et donc une modification du ROWID
des lignes déplacées. Par défaut, un tel déplacement n’est pas autorisé. Pour autoriser le
déplacement des lignes de la table, vous pouvez exécuter l’ordre SQL ALTER TABLE
nom_table ENABLE ROW MOVEMENT. Lors du déplacement des lignes et de la modification
du ROWID, Oracle met à jour les index.
L’opération de SHRINK peut être effectuée en ligne et des mises à jour parallèles sont
possibles ; un verrou exclusif est posé sur la table uniquement au moment du compactage
du segment proprement dit (déplacement de la HWM et libération de l’espace récupéré).
21 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
Le compactage du segment peut poser des problèmes si des longues requêtes de lecture
sont en cours sur la table ; c’est la raison pour laquelle il est possible de dissocier les deux
phases du traitement.
Exemple
22 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
Sur cet exemple, nous voyons que le SHRINK SPACE a bien compacté les lignes dans des
blocs et libéré l’espace.
Syntaxe
Exemple :
Les options sont les mêmes que celles de l’ordre SQL CREATE TABLE.L’ordre SQL ALTER
TABLE ... MOVE est très intéressant car toutes les options de stockage peuvent être
modifiées, dont le tablespace. De plus, les objets dépendants sont préservés.
Le principe mis en œuvre est de recopier physiquement les données des extensions
actuellement allouées vers une ou plusieurs nouvelles extensions allouées ailleurs. Les
extensions initiales sont libérées à la fin du traitement : la table initiale est donc intacte
en cas d’échec, mais il faut un espace disponible au moins égal à la taille initiale de la
table pendant la reconstruction.
Les lignes étant physiquement déplacées, les ROWID changent mais les index ne sont pas
mis à jour en temps réel par Oracle ; ils sont invalidés (statut UNUSABLE).Après avoir
reconstruit la table, il faudra reconstruire les index (ordre SQL ALTER INDEX ... REBUILD).
23 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
Pendant le traitement, la table n’est pas disponible en mise à jour ; par contre, elle est
accessible en lecture (le segment initial est préservé). Cette technique de reconstruction
est plus simple à mettre en œuvre, et donc moins risquée, que les techniques de
recréation. C’est sans conteste LA technique à utiliser depuis la version 8i pour réorganiser
le stockage d’une table (ou d’un tablespace, en réalisant l’opération sur toutes les tables
du tablespace).
Exemple 1
• Situation de départ
• Reconstruction
• Situation à l’arrivée (après calcul des statistiques et analyse des lignes chaînées ou
migrées)
24 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
-----------------
0
Par ailleurs, le tablespace DATA est un tablespace géré localement avec une gestion
uniforme des extensions (10 Mo, soit 1 280 blocs) et une gestion automatique de l’espace
dans les segments ; il peut être mieux adapté à la volumétrie future de la table.
Exemple 2
• Situation de départ
Plusieurs vues du dictionnaire de données permettent d’obtenir des informations sur les
tables :
25 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
• DBA_EXTENTS : informations sur les extensions allouées aux segments (dont ceux de
type table) ;
• DBA_TAB_MODIFICATIONS : informations sur les tables surveillées.
Les vues DBA_SEGMENTS et DBA_EXTENTS ont été présentées à la section Trouver des
informations sur les tablespaces et les fichiers de données du chapitre Gestion des
tablespaces et des fichiers de données.
DBA_TABLES
LOGGING : Indique si le mode LOGGING est actif ou non pour la table (YES ou NO).
DBA_TAB_COLUMNS
DATA_LENGTH : Longueur.
26 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
DATA_PRECISION : Précision.
DATA_SCALE : Échelle.
* Statistiques sur les colonnes, calculées par défaut lorsque les statistiques sont générées
sur la table.
DBA_TAB_MODIFICATIONS
Un index est une structure définie sur une ou plusieurs colonnes d’une table ; la (les)
colonne(s) constitue(nt) la clé de l’index.
L’index permet un accès rapide aux lignes de la table lors d’une recherche basée sur la clé
de l’index. La notion d’index est analogue à celle de l’index d’un livre : pour rechercher
27 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
un mot dans un livre, il est plus rapide de regarder d’abord dans l’index, ce dernier
donnant les numéros des pages qui contiennent le mot. Un index est physiquement et
logiquement indépendant de la table. Il peut être créé/supprimé sans affecter la table de
base (sauf impact sur les performances lorsque l’index est supprimé). Un index nécessite
son propre espace de stockage.
• utilisés lors des recherches si une clé d’index est mentionnée dans la clause WHERE
d’une requête ;
• actualisés à chaque mise à jour (INSERT, UPDATE, DELETE).
• Unique: une valeur de la clé d’index n’est présente qu’une fois dans la table.
• Non unique : une valeur de la clé d’index peut être présente plusieurs fois dans la
table.
Oracle préconise de ne pas créer d’index unique explicitement mais de définir des
contraintes d’intégrité (PRIMARY KEY ou UNIQUE) pour lesquelles Oracle crée
automatiquement des index uniques. Les index non uniques, par contre, doivent être créés
explicitement.
Un index peut être composé (concaténé). Dans ce cas, la clé d’index contient plusieurs
colonnes de la table ; elles ne sont pas toujours adjacentes dans la table, ni forcément
placées dans le même ordre que dans la table.
Les valeurs NULL ne sont pas stockées dans les index B-tree et ne sont donc pas prises en
compte vis-à-vis de l’unicité : deux lignes de la table peuvent avoir la valeur NULL dans la
colonne concernée.
28 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
Les blocs branches (branch blocks) contiennent des données qui pointent vers des blocs de
niveau inférieur. Les blocs branches permettent d’assurer un aiguillage d’un bloc racine
vers les blocs feuilles, en éliminant des branches à chaque niveau.
Les blocs feuilles (leaf blocks) contiennent les différentes valeurs de la clé d’index avec
les ROWID des lignes de la table correspondante. Pour un index unique, il existe un seul
ROWID par valeur de clé ; pour un index non unique, plusieurs ROWID sont possibles pour
chaque valeur de clé. Les blocs feuilles pointent vers les lignes de la table.
Lorsque l’index est utilisé pour rechercher une valeur de clé, le bloc racine est lu, puis le
bloc feuille de niveau inférieur correspondant à la branche qui contient la valeur de clé
est lu à son tour, et ainsi de suite jusqu’au bloc feuille qui contient la valeur de
clé ; associé à cette valeur de clé, Oracle va trouver le(s) ROWID(s) de la ou les lignes qui
contiennent la valeur de la clé et pouvoir ainsi les lire directement dans la table.
Les blocs feuilles sont doublement chaînés pour faciliter le parcours de l’index.
Dans les blocs feuilles d’un index non unique, les données sont triées sur la clé puis sur le
ROWID ; la valeur de la clé est répétée à chaque fois.
À l’image de la table, un bloc d’index comprend les données proprement dites et des
informations de contrôle (en-tête de bloc, en-tête de ligne, etc.).
29 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
L’index améliore la performance des requêtes (SELECT, UDATE et DELETE) qui utilisent la
clé de l’index dans la clause WHERE.
L’arbre est maintenu équilibré par Oracle. Dans "B-tree", "B" signifie balanced (balancé),
c’est-à-dire qu’Oracle s’arrange pour maintenir son arbre équilibré au fur et à mesure des
mises à jour de l’index. Pour cela, Oracle peut couper des blocs en cas de besoin (notion
de split).
En conséquence, toutes les valeurs de la clé dans les blocs feuilles sont situées à la même
profondeur de l’arbre et donc accessibles en parcourant le même nombre de blocs. La
recherche de n’importe quelle valeur de clé prend toujours à peu près le même temps.
• La longueur d’une ligne de l’index est égale à 8 octets (longueur du type DATE) +
6 octets (longueur du ROWID) + quelques octets pour les informations de contrôle
(arrondi à 6 octets) = 20 octets.
• Avec une taille de bloc (DB_BLOCK_SIZE) de 8 Ko, l’espace disponible dans le bloc
est égal à 8 192 octets - taille de l’en-tête (entre 100 et 200 octets, prenons 192
octets pour notre exemple) = 8 000 octets, rempli à 90 % = 7 200 octets.
• Un bloc peut donc stocker environ 7 200 / 20 = 360 clés.
• Un arbre d’une profondeur de 3 peut donc gérer 360 x 360 x 360 = 466 millions de
clés.
• Pour retrouver une valeur parmi les 466 millions, 3 entrées/sorties sont suffisantes
dans l’index plus une entrée/sortie dans la table afin de lire chaque ligne.
De plus, si les colonnes utilisées dans les différentes clauses de la requête sont toutes
présentes dans l’index, Oracle n’a pas besoin d’accéder à la table. Si un index composé
existe sur les colonnes (NOM,PRENOM) de la table ADHERENT, la requête suivante
n’accède pas à la table :
30 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
Les colonnes candidates à l’indexation sont les colonnes fréquemment présentes dans les
clauses WHERE, comme critère de sélection ou de jointure.
Pour trouver les bonnes colonnes candidates à l’indexation, il faut analyser les requêtes
SELECT, UPDATE et DELETE, et rechercher les colonnes les plus fréquemment utilisées
dans les clauses WHERE (critère de sélection et jointure).
Prenons l’exemple de la table ADHERENT comprenant 100 000 personnes avec une
répartition homogène homme/femme. Considérons les clauses WHERE suivantes :
Ces exemples montrent que la colonne NUMERO est intrinsèquement sélective mais que
certaines requêtes basées sur cette colonne peuvent ne pas l’être ; par contre, la colonne
SEXE n’est pas intrinsèquement sélective.
Une colonne ayant peu de valeurs distinctes est intrinsèquement non sélective. Parmi les
colonnes candidates à l’indexation, il faut donc identifier celles qui sont intrinsèquement
sélectives et utilisées dans des requêtes elles-mêmes sélectives ; une colonne sera
effectivement une bonne candidate à l’indexation si la sélectivité (de la colonne et des
requêtes qui l’utilisent) est inférieure à environ 5 à 10 %. Dans les grandes lignes, si une
requête utilisant un index ramène plus de 10 % des lignes, Oracle se révèlera plus
performant en réalisant un parcours complet de la table qu’en passant par l’index.
Cette règle des 5 à 10 % n’est pas en soi une garantie de performance effective de
l’index ; de nombreux autres facteurs entrent en ligne de compte. C’est néanmoins un bon
critère de départ, qu’il faut valider en réalisant des tests.
Parmi les colonnes candidates, il faudra d’abord identifier les colonnes qui sont
systématiquement présentes ensembles dans la clause WHERE : ce sont de bonnes
candidates à la création d’un index composé qui est généralement plus sélectif qu’un
index simple. En effet, si les colonnes C1 et C2 d’une table sont fréquemment utilisées
31 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
ensembles dans les clauses WHERE et qu’il existe 10 valeurs distinctes pour C1 (sélectivité
de 10 %) et 10 valeurs distinctes pour C2 (sélectivité de 10 %), la sélectivité théorique du
couple (C1,C2) est de 1 % (dans l’hypothèse où il n’y a pas de corrélation entre C1 et C2).
Indexer les petites tables ne sert à rien car le nombre minimum d’entrées/sorties lors d’un
accès par index est de 2 (1 entrée/sortie au minimum pour l’index et 1 entrée/sortie au
minimum pour la table). Or, grâce au paramètreDB_FILE_MULTIBLOCK_READ_COUNT
(DBFMRC ci-après), Oracle peut lire DBFMRC blocs en une entrée/sortie lors d’un parcours
complet de table. Donc, si la taille de la table est inférieure à DBFMRC blocs, un index est
moins performant que le parcours complet ; si la taille de la table est inférieure à 2 x
DBFMRC blocs, un index est aussi performant (mais pas plus) que le parcours complet.
Ainsi, en général, indexer des tables comprenant quelques dizaines de blocs n’apporte
rien.
Les valeurs NULL ne sont pas stockées dans les index B-tree ; donc, indexer une colonne
pour améliorer les recherches IS NULL ne sert à rien. Hormis les index uniques, il n’est
jamais certain qu’un index soit réellement performant ; il faut donc le tester. Lors des
tests sur les index, il ne faut pas oublier de vérifier si les index ne dégradent pas trop les
performances des mises à jour.
L’ordre des colonnes est important dans un index composé. Un index composé est utilisé si
les colonnes de tête de la clé d’index sont présentes dans la condition.
Si un index composé existe sur les colonnes (NOM,PRENOM) de la table ADHERENT, les trois
requêtes suivantes utilisent l’index :
Dans certains cas, si la première colonne de l’index a très peu de valeurs distinctes (par exemple
2), Oracle est susceptible de subdiviser l’index en sous-index (un pour chaque valeur de la
première colonne) et de parcourir chaque sous-index.
Dans certaines situations, il peut être intéressant d’ajouter dans la clé d’index des
colonnes présentes dans la clause SELECT, pour éviter d’accéder à la table.
32 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
Abuser de cette astuce et placer de nombreuses colonnes dans la clé d’index peut rendre l’index
moins performant. Plus la clé d’index est longue, moins il y a de clés par bloc, et plus l’index est
volumineux et profond, ce qui augmente le nombre d’entrées/sorties pour parcourir l’index.
Par ailleurs, il faut s’assurer que l’écriture des requêtes n’empêche pas l’index d’être
utilisé.
Exemples de clauses WHERE où l’index présent sur la colonne nom n’est pas utilisé :
nom IS NULL
Les recherches LIKE n’utilisent pas l’index si le début de la chaîne n’est pas connu
(recherches du type "contient", "se termine par").
SUBSTR(nom,1,1) =’H’
Ce n’est pas parce qu’une requête n’empêche pas l’utilisation d’un index, que l’index est
réellement utilisé. C’est l’optimiseur Oracle qui décidera d’utiliser ou non un index, en fonction
des caractéristiques de la requête, de la table et des index (c’est un vaste sujet).
33 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
Le stockage d’un index peut être spécifié lors de la création de l’index, dans l’ordre SQL
CREATE INDEX.
Syntaxe simplifiée
Exemple :
Les clauses TABLESPACE et STORAGE ont déjà été présentées au chapitre Gestion des
tablespaces et des fichiers de données. N’oubliez pas que la clause STORAGE est traitée
différemment selon que le tablespace est géré par le dictionnaire ou localement. Dans un
tablespace géré localement, seule l’option INITIAL est utile.
La clause ONLINE permet d’autoriser les mises à jour sur la table pendant la construction
de l’index.
La clause COMPRESS [n] permet de compresser la clé d’index, uniquement dans le cas d’un
index composé. Pour compresser la clé d’index, Oracle élimine les occurrences répétées
des valeurs des colonnes de la clé. L’option n permet de préciser le nombre de colonnes
de la clé à compresser. Par défaut, n est égal au nombre de colonnes moins un pour un
index unique et au nombre de colonnes pour un index non unique. Compresser la clé des
index composés peut permettre de réduire sensiblement la taille de l’index. Pour obtenir
un résultat optimal, il faut compresser sur la portion de tête de la clé comprenant le plus
grand nombre de répétitions (cette information peut être obtenue avec l’ordre SQL
ANALYZE INDEX ... VALIDATE STUCTURE présenté plus loin).
La clause NOLOGGING permet de ne pas journaliser la création de l’index ; les mises à jour
individuelles sont, par contre, toujours journalisées. Les considérations sont les mêmes
que pour une table (cf. Gestion des tables) mais un index est moins critique qu’une
table ; si un index n’est pas récupérable, il est toujours possible de le reconstruire.
34 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
Il existe aussi un ordre SQL ALTER INDEX mais, comme pour une table, il n’a pas d’effet
rétroactif sur ce qui est déjà alloué ; généralement, en cas de besoin, l’index sera plutôt
reconstruit.
Le stockage de l’index d’une clé primaire ou unique peut être spécifié lors de la définition
de la contrainte grâce à l’option USING INDEX de la clause CONSTRAINT.
Syntaxe
Exemple :
Par défaut, lorsqu’une contrainte de clé primaire ou de clé unique est créée ou activée,
Oracle regarde s’il existe un index utilisable pour vérifier la contrainte. Cet index peut
35 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
être unique ou non unique, mais doit posséder une clé égale à ou commençant par la clé
de la contrainte. Si un tel index n’existe pas, Oracle crée un index unique pour vérifier la
contrainte, index dont la clé est égale à la clé de la contrainte. Dans ce cas, l’option
USING INDEX de la clause CONSTRAINT permet de spécifier les caractéristiques de stockage
de cet index.
Dans les deux cas, les autres options de la clause USING INDEX sont interdites.
L’index mentionné ou créé peut être unique ou non unique mais il doit être "compatible"
avec la contrainte de clé primaire ou unique. Si l’index est unique, la clé de l’index doit
être égale à la clé de la contrainte (mêmes colonnes, dans le même ordre). Si l’index est
non unique, la clé de l’index doit être égale à ou commencer par la clé de la contrainte.
Exemple :
Utiliser une des deux clauses USING INDEX apparues dans Oracle9i permet :
36 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
L’origine de l’index (créé par Oracle, déjà existant, créé dans l’ordre de définition de la
contrainte) n’a pas d’impact.
Depuis Oracle9i, il est possible d’indiquer explicitement si l’index associé à une contrainte
supprimée doit être conservé ou supprimé.
Syntaxe
A priori, conserver un index unique lors de la suppression d’une contrainte de clé primaire
ou unique n’a pas de sens : l’unicité est toujours vérifiée au niveau de l’index.
L’approche par défaut d’Oracle est relativement logique. Si une contrainte de clé primaire
ou de clé unique est supprimée, c’est notamment que l’unicité n’est plus
souhaitée ; supprimer l’index associé est donc logique. Par contre, un index non unique ne
vérifie pas l’unicité et peut donc être conservé, même lorsque la contrainte est
supprimée.
Créer systématiquement des index non uniques pour gérer les contraintes de clé primaire et de clé
unique est intéressant, et laisse en tout état de cause le choix de conserver ou non l’index lors de
la suppression ou de la désactivation de la contrainte.
Les recommandations sont les mêmes que pour les tables (section Gestion des tables) :
Définir un index en spécifiant un INITIAL adapté à la volumétrie estimée de l’index, peut améliorer
la performance de création de l’index, en diminuant le nombre d’extensions allouées pendant
l’opération.
37 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
Là encore, le plus simple et le plus pragmatique consiste à procéder comme pour une
table :
Supposons, par exemple, que la table ADHERENT (schéma DIANE) ait été chargée avec
10 000 lignes et qu’elle doit en contenir 250 000 à une échéance de 6 mois. Nous pouvons
réaliser le calcul suivant pour un de ces index :
L’index pour le jeu de données utilise 59 blocs, donc par règle de trois, nous pouvons
estimer que l’index utilisera 1 475 blocs dans 6 mois.
L’emploi de l’ordre SQL ANALYZE INDEX ... VALIDATE STRUCTURE est présenté plus loin.
c. Estimation de PCTFREE
Vous n’avez pas besoin de vous préoccuper de PCTFREE si la colonne indexée est vide lors
de la création de l’index. Pour mémoire, PCTFREE est pris en compte uniquement à la
création de l’index et n’est effectivement utilisé que si la colonne à indexer est non vide.
Vous pouvez positionner PCTFREE à une valeur faible (éventuellement 0) dans les cas
suivants :
• Si l’index est créé sur une colonne qui sera rarement mise à jour (ni UPDATE ni
INSERT).
• Si l’index est créé sur une colonne qui va continuer à faire l’objet d’insertions avec
des valeurs en dehors de la plage des valeurs actuelles (ces entrées d’index iront
dans de nouveaux blocs).
Dans le cas où l’index est créé sur une colonne non vide, l’objectif de PCTFREE est
simple : réserver de l’espace dans les blocs pour les éventuelles futures insertions de clés
38 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
dans les blocs d’index initialement utilisés (les clés sont triées dans les blocs feuilles). Si
pour une raison quelconque, les futures insertions de clés ne risquent pas de venir dans les
blocs déjà utilisés, il est possible de mettre un PCTFREE faible ou nul.
Vous devez par contre positionner PCTFREE à une valeur élevée dans les cas suivants :
• Si l’index est créé sur une colonne qui sera souvent mise à jour (UPDATE).
• Si l’index est créé sur une colonne qui va continuer à faire l’objet d’insertions avec
des valeurs appartenant à la plage des valeurs actuelles (ces entrées viendront
s’intercaler dans les blocs existants).
Nf est une valeur relativement arbitraire, Nf - Ni étant le nombre de lignes à insérer dans
l’index avant que tout l’espace laissé libre initialement soit occupé (statistiquement), et
que Oracle doit commencer à réorganiser son arbre d’index.
Une valeur arbitraire de PCTFREE peut être utilisée (10 à 20 %), sachant qu’il est facile de
superviser le stockage d’un index et de le reconstruire en cas de besoin.
Lorsqu’une clé d’index est modifiée, l’entrée correspondante est supprimée et recréée. Lorsque
des entrées sont supprimées dans un bloc d’index, l’espace libéré ne peut être réutilisé que pour
des entrées dont c’est la place (les données sont triées dans les blocs feuilles). Pour pouvoir
réutiliser un bloc et y placer des valeurs complètement différentes, il faut que le bloc soit
complètement vide.
Pour obtenir des informations plus détaillées sur le stockage d’un index, vous pouvez :
• utiliser les informations calculées par le package DBMS_SPACE (voir le point Gestion
des tables) ;
• employer les statistiques générées par le package DBMS_STATS ;
• utiliser d’autres statistiques calculées par l’ordre SQL ANALYZE INDEX ... VALIDATE
STRUCTURE.
39 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
Les statistiques générées par le package DBMS_STATS ne sont pas suffisantes pour réaliser
une analyse détaillée du stockage de l’index (mais elles sont suffisantes pour
l’optimiseur) ; nous ne les évoquerons donc, pas ici (description de la vue DBA_INDEXES au
point Trouver des informations sur les index).
Nous allons par contre, présenter l’utilisation de l’ordre SQL ANALYZE INDEX ... VALIDATE
STRUCTURE.
L’ordre SQL ANALYZE INDEX ... VALIDATE STRUCTURE permet de vérifier l’intégrité de
l’index et d’obtenir des informations détaillées sur le stockage de l’index.
Syntaxe
Exemple :
L’ordre SQL ANALYZE INDEX ... VALIDATE STRUCTURE ne vérifie pas la cohérence de
l’index vis-à-vis de la table ; pour vérifier une telle cohérence, il faut ajouter l’option
CASCADE. Le résultat peut être consulté dans la vue INDEX_STATS :
PCT_USED : pourcentage de l’espace alloué à l’index qui est utilisé (entre 0 et 100).
La vue INDEX_STATS ne donne que le résultat du dernier ANALYZE INDEX ... VALIDATE STRUCTURE.
40 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
Les statistiques générées par l’ordre SQL ANALYZE INDEX ... VALIDATE STRUCTURE ne sont
pas utilisées par l’optimiseur.
Exemple :
• Situation après une forte activité de mises à jour (uniquement UPDATE) sur la table
Dans cet exemple, nous voyons que des blocs supplémentaires ont été alloués à l’index et
ont été utilisés, mais avec une dégradation du taux d’occupation. La colonne
DEL_LF_ROWS montre que des entrées ont été supprimées, alors qu’il n’y a eu aucune
suppression dans la table ; mais, comme nous l’avions indiqué précédemment, une
modification de clé d’index se traduit par une suppression (d’où les DEL_LF_ROWS) puis
une insertion (d’où l’utilisation éventuelle de nouveaux blocs).
Les problèmes possibles sur le stockage d’un index sont les suivants :
Il y a de l’espace inutilisé alloué à un index si le nombre de blocs occupés est faible par
rapport au nombre de blocs alloués, et si l’index ne va plus grossir (ou peu).
Le nombre de blocs occupés est donné par la somme de la valeur des colonnes LF_BLKS et
BR_BLKS de la vue INDEX_STATS et le nombre de blocs alloués par la valeur de la colonne
BLOCKS de la vue INDEX_STATS.
Exemple :
41 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
occupés alloués
-------- --------
116 128
Ce premier problème n’a pas d’incidence sur les performances (les blocs au-delà de la
HWM ne sont jamais lus) ; il conduit juste à un gaspillage d’espace disque.
Faible taux d’occupation moyen des blocs et/ou profondeur importante de l’index
Le stockage interne d’un index peut être considéré comme dégradé si une ou plusieurs des
conditions suivantes sont vérifiées :
Un mauvais remplissage des blocs peut être lié à une valeur inadaptée de PCTFREE lors de
la création de l’index et/ou à un index très volatile (nombreuses mises à jour). Ce
deuxième problème a des incidences sur les performances et sur l’utilisation de l’espace
dans le Database Buffer Cache. Moins les blocs sont pleins, plus l’index est volumineux et
profond, ce qui augmente le nombre d’entrées/sorties pour le parcours de l’arbre.
Un index créé sur une table très volumineuse peut avoir un arbre profond. Ce qu’il faut
donc surveiller, c’est davantage la dégradation au fil du temps (surtout si la volumétrie de
la table reste par ailleurs, stable) qu’une situation à un instant donné.
Exemple :
• Avant
• Après
Sur cet exemple, le stockage de l’index s’est dégradé au fil du temps (alors que la
volumétrie de la table n’a pratiquement pas changé).
42 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
Plusieurs techniques sont à notre disposition pour réorganiser le stockage d’un index :
Il est évidemment aussi possible de supprimer l’index (ordre SQL DROP INDEX) puis de le
créer de nouveau (ordre SQL CREATE INDEX), mais une reconstruction (ordre SQL ALTER
INDEX ... REBUILD) se révèle généralement plus intéressante.
Le tableau suivant résume les techniques envisageables (√) et celles qui sont les mieux
adaptées (☺) à tel ou tel besoin :
Réorganiser le stockage d’un index est moins compliqué que réorganiser le stockage d’une
table car les données ne sont pas affectées et la table est toujours accessible et
pleinement opérationnelle.
Lors d’un traitement massif sur une table (chargement, purge), il peut être intéressant de
supprimer tout ou partie des index de la table avant le traitement et de les recréer ensuite. La
performance globale est meilleure et l’index est neuf (non dégradé) à l’arrivée.
L’ordre SQL ALTER INDEX ... DEALLOCATE UNUSED permet de libérer l’espace d’un index
situé au-dessus de la HWM.
Syntaxe
Exemple :
43 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
Le fonctionnement est le même que pour une table (Gestion des tables). N’oubliez pas que
l’espace initialement alloué est par défaut préservé ; il faut utiliser la clause KEEP pour
libérer de l’espace à l’intérieur de l’espace initialement alloué à l’index.
L’ordre SQL ALTER INDEX ... COALESCE permet de fusionner le contenu de blocs feuilles
adjacents qui contiennent de l’espace libre. Grosso modo, deux blocs feuilles adjacents
qui ont 50 % d’espace libre peuvent être fusionnés en un seul bloc, ce qui libère un bloc.
Syntaxe
L’ordre SQL ALTER INDEX ... COALESCE n’effectue, par contre, aucune opération sur les
blocs branches ; la profondeur de l’arbre ne change pas. Cette opération est relativement
rapide et ne nécessite pas d’espace de stockage supplémentaire.
Exemple :
• Situation de départ
• Situation après des modifications importantes dans la table : l’index est dégradé (la
profondeur a changé)
• Opération de COALESCE
44 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
Dans de nombreuses situations, cette simple opération de COALESCE est suffisante pour
retrouver un index performant.
L’ordre SQL ALTER INDEX ... SHRINK SPACE est analogue à l’ordre SQL ALTER TABLE ...
SHRINK SPACE : il permet de compacter les lignes d’un index, mais uniquement pour un
index stocké dans un tablespace géré localement avec une gestion automatique de
l’espace dans les segments. Par défaut, Oracle compacte aussi le segment, ajuste la HWM
et libère l’espace ainsi récupéré.
Syntaxe
Avec l’option COMPACT, Oracle se contente de compacter les lignes, mais sans ajuster la
HWM ni libérer d’espace. L’exécution ultérieure d’un autre ordre SQL ALTER TABLE ...
SHRINK SPACE permettra de terminer l’opération.
L’ordre SQL ALTER INDEX ... SHRINK SPACE COMPACT est équivalent à l’ordre SQL ALTER
INDEX ... COALESCE.
Exemple
• Situation après des modifications importantes dans la table : l’index est dégradé.
À quelques blocs près, l’opération de SHRINK SPACE donne le même résultat que
l’opération de COALESCE, sauf sur les blocs utilisés (400 contre 640) ; l’espace a été
libéré.
45 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
L’opération de COALESCE est légèrement plus rapide que l’opération de SHRINK SPACE.
L’ordre SQL ALTER INDEX ... REBUILD permet de reconstruire en totalité un index (blocs
branches et blocs feuilles) et donc, de réorganiser son stockage.
Syntaxe
Exemple :
Les options sont les mêmes que celles de l’ordre SQL CREATE INDEX.
Sans option, l’ordre SQL ALTER INDEX ... REBUILD reconstruit l’index avec les mêmes
clauses de stockage. Cette syntaxe peut être utilisée pour reconstruire un index dont les
clauses de stockage sont bonnes mais qui s’est dégradé au fil du temps, du fait d’une forte
activité de mise à jour.
L’ordre SQL ALTER INDEX ... REBUILD est plus intéressant que la recréation
(DROP+CREATE) pour deux raisons :
• L’index est reconstruit à partir de l’index existant : aucun tri n’est nécessaire.
• L’ancien index est toujours disponible : les requêtes peuvent l’utiliser.
L’inconvénient majeur par rapport à une recréation est qu’il faut de l’espace disponible
pour faire cohabiter temporairement l’ancien index et le nouveau.
Exemple 1
• Situation après des modifications importantes dans la table : l’index est dégradé
46 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
• Opération de REBUILD
Exemple 2
L’index a été reconstruit avec une compression sur les deux premières colonnes. Le gain
annoncé était de 28 % ; il est de 28,8 %.
f. Conclusion
47 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
Par contre, si vous avez des problèmes de place, vous pouvez employer le COALESCE pour
un résultat généralement très satisfaisant, mais vous ne libérez pas d’espace pour d’autres
segments. Dans ce cas, le SHRINK SPACE peut être envisagé ; il présente l’avantage de
libérer l’espace récupéré.
Depuis Oracle9i, il est possible de surveiller les index afin de déterminer s’ils sont utilisés
ou non. Un index non utilisé peut être supprimé pour libérer de l’espace et améliorer les
performances des mises à jour.
L’ordre SQL ALTER INDEX permet d’activer ou de désactiver la surveillance d’un index :
Exemple :
La clause MONITORING USAGE peut aussi être utilisée dans l’ordre SQL CREATE INDEX pour
activer la surveillance dès la création de l’index (NOMONITORING par défaut).
La vue V$OBJECT_USAGE sera ensuite interrogée pour déterminer si un index a été utilisé
pendant qu’il était sous surveillance :
USED : Indique si l’index a été utilisé au moins une fois pendant sa surveillance (YES ou
NO).
Exemple :
48 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
01/04/2005 10:37:40
Dans cet exemple, l’index ADHERENT$IX01 créé sur la table ADHERENT a été utilisé au
moins une fois depuis que l’index est sous surveillance ; l’index est toujours sous
surveillance (la colonne END_MONITORING est vide).
Plusieurs vues du dictionnaire de données permettent d’obtenir des informations sur les
index :
Les vues DBA_SEGMENTS et DBA_EXTENTS ont été présentées à la section Trouver des
informations sur les tablespaces et les fichiers de données du chapitre Gestion des
tablespaces et des fichiers de données.
La vue INDEX_STATS a été présentée à la section Gestion des index B-tree. L’ordre SQL
ANALYZE INDEX ... VALIDATE STRUCTURE.
Les colonnes intéressantes des différentes autres vues sont présentées ci-après.
DBA_INDEXES
LOGGING : Indique si le mode LOGGING est actif ou non pour l’index (YES ou NO).
49 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
BLEVEL * : Profondeur de l’arbre au niveau des branches (ne tient pas compte des
feuilles). 0 si le bloc racine est égal au bloc feuille.
* Statistiques sur l’index, calculées par défaut lorsque les statistiques sont générées sur la
table. Ces dernières sont utilisées par l’optimiseur.
DBA_IND_COLUMNS
Pour fonctionner, l’optimiseur dans le mode CBO a besoin de statistiques sur les tables, les
colonnes et les index. Ces statistiques sont calculées avec le package DBMS_STATS.
50 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
Depuis la version 10, les statistiques sont automatiquement collectées par Oracle. En
version 11, cette collecte s’effectue par l’intermédiaire d’une tâche de maintenance
automatisée (cf. Oracle Enterprise Manager Database Control du chapitre Les Outils
d’administration).
Par défaut, cette tâche de maintenance collecte les statistiques sur les objets de la base
de données qui n’ont pas de statistiques ou qui ont des statistiques jugées obsolètes (si
plus de 10% des lignes de l’objet sous-jacent ont été modifiées) ; la procédure traite en
priorité les objets qui en ont le plus besoin. Les paramètres de cette tâche automatique
peuvent être configurées dans le Database Control (cf. Oracle Enterprise Manager
Database Control du chapitre Les Outils d’administration).
Ces procédures ont d’autres paramètres dont les valeurs par défaut sont a priori
satisfaisantes (au moins dans un premier temps).
Les statistiques peuvent êtres consultées dans les vuesDBA_TABLES, DBA_TAB_ COLUMNSet
DBA_INDEXES.
Exemple :
51 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
d’accueil puis sur le lien Gérer les statistiques de l’optimiseur (cadre Optimiseur
d’interrogation).
Dans le Database Control, cliquez sur le lien Schéma sur la page d’accueil puis sur le lien
Tables (cadre Objets de base de données) pour accéder à la page de gestion des tables.
La section Rechercher permet de rechercher des objets selon leur type, leur schéma ou
leur nom.
À partir de cette page, vous pouvez effectuer diverses actions sur les tables :
52 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
En cliquant sur le lien du nom de table, ou en cliquant sur les boutons Créer, Modifier ou
Visualiser, vous arrivez sur la page de définition d’une table :
Cette page propose plusieurs onglets (sous forme de liens) permettant de gérer les
différentes caractéristiques de la table.
L’onglet Segments permet de voir l’espace utilisé par la table et ces index :
53 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
2. Les index
Dans le Database Control, cliquez sur le lien Schéma sur la page d’accueil puis sur le lien
Index (cadre Objet de base de données) pour accéder à la page de gestion des index.
54 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
La section Rechercher permet de rechercher des objets selon leur type, leur schéma ou
leur nom.
À partir de cette page, vous pouvez effectuer diverses actions sur les index :
En cliquant sur le lien du nom d’index, ou en cliquant sur les boutons Créer, Modifier ou
Visualiser, vous arrivez sur la page de définition d’un index :
55 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
Cette page propose plusieurs onglets (sous forme de liens) permettant de gérer les
différentes caractéristiques de l’index. L’onglet Segments permet de voir l’espace utilisé
par l’index (comme pour une table).
Le menu Réorganiser disponible sur les tables, les index et les tablespace permet
d’exécuter un assistant de réorganisation du stockage des objets. Cet assistant peut aussi
être appelé en cliquant sur le lien Réorganiser les objets dans le cadre Objets de base de
données de l’onglet Schéma.
Sur cette page, vous pouvez définir la liste des objets à réorganiser en cliquant sur les
boutons Ajouter et Enlever. Les boutons Définir les attributs et Définir les attributs par
type permettent de spécifier les caractéristiques de stockage : nouveau tablespace, taille
initiale, PCTFREE, etc.
Rapport d’impact
Cette page donne des informations sur les problèmes potentiels qui peuvent survenir au
cours de la réorganisation (manque d’espace par exemple) ; si c’est le cas, il faut réaliser
les modifications nécessaires avant de lancer l’opération.
Programmation
Récapitulatif
56 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
Cette page donne un récapitulatif du travail qui va être effectué. En cliquant sur le bouton
radio Script complet, vous pouvez consulter (et récupérer) le script complet de la
réorganisation. Cliquez sur le bouton Soumettre un travail pour lancer l’opération.
Le résultat du travail peut être consulté en cliquant sur le lien Travaux de la page
d’accueil (cadre Liens associés en bas).
Le Database Control dispose d’un conseiller sur les segments (Segment Advisor). Ce
conseiller donne des recommandations sur l’opportunité ou non de compacter (SHRINK) un
segment.
Cet assistant peut être appelé en utilisant le menu Exécuter la fonction de conseil sur les
segments disponible sur les tables, les index et les tablespace ou en cliquant sur le lien
Fonction de conseil sur les segments sur la page Centre de conseil (accessible par le lien
Centre de conseil à partir de la page d’accueil).
Par défaut, cet assistant est aussi programmé pour s’exécuter en tâche de maintenance
automatisée (cf. Oracle Enterprise Manager Database Control du chapitre Les Outils
d’administration). Vous serez donc rarement amené à lancer le conseiller manuellement.
Sur la page d’accueil du Database Control, dans le cadre Récapitulatif de l’espace, pour
pouvez voir rapidement s’il y a des recommandations sur les segments :
57 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
En cliquant sur le lien associé, vous pouvez afficher la liste des recommandations :
Si vous cliquez sur le bouton Détails des recommandations, vous pouvez consulter le détail
de la recommandation sélectionnée :
58 | P a g e
Support de Cours ORACLE 11g : Administration, par Mawunya Koffi GBENOU
Cette page vous permet de choisir une option de réduction (SHRINK SPACE ou SHRINK
SPACE COMPACT) et de soumettre le travail (bouton Implémenter). Le résultat du travail
peut être consulté en cliquant sur le lien Travaux de la page Serveur (cadre Oracle
Scheduler).
D’une manière plus générale, les résultats des différents conseillers sont visibles lorsque
vous affichez la page Centre de conseil :
En cliquant sur le lien correspondant à une tâche, vous pouvez visualiser les
recommandations du conseiller.
59 | P a g e