Résumé SQL Tuning
Résumé SQL Tuning
Les données sur disque sont stockées en fichiers constitués de pages, qui servent d'unité
d'échange entre le disque et la mémoire. Le coût des opérations en BDD est principalement
mesuré en nombre d’E/S de pages. Chaque fichier contient des enregistrements de taille fixe ou
variable, identifiés par un ROWID, composé de l’adresse de la page et de l’indice de
l’enregistrement dans celle-ci.
Les principaux processus Oracle incluent PMON, SMON, DBWR, LGWR, ARCn,
assurant la gestion et l’optimisation des bases de données.
Architecture Multitenant
Permet une base de données conteneur (CDB) pouvant héberger plusieurs bases de
données enfichables (PDB).Un conteneur (CDB) est une collection logique de métadonnées et de
données. Une PDB est une collection logique portable de schémas et objets. Avant Oracle 12c,
les bases de données étaient non-CDB.
Contient un conteneur racine (CDB$ROOT) avec les métadonnées Oracle. Une base
d’amorçage (PDB$SEED) sert de modèle pour créer de nouvelles PDB. Une ou plusieurs PDB
contenant les données utilisateur (tables, index, etc.).
Une base de données à instance unique a une relation un-à-un entre l'instance et la base de
données. Oracle RAC permet une relation un-à-plusieurs, avec jusqu'à 100 instances accédant à
une seule BD.Toutes les instances partagent les mêmes fichiers de BD via un stockage partagé
géré par ASM (Automatic Storage Management).
Optimisation algébrique
Un plan d’exécution logique est arbre algébrique qui décrit les étapes d’exécution
logique d’une requête sous forme d’opérations algébriques, telles que la projection, la restriction,
l’union, la jointure...
Un plan d’exécution optimale est obtenu suite à une réécriture algébrique basée sur un
ensemble de règles appliquées sur les opérateurs algébriques se trouvant dans le plan initial.
Le passage d’une requête SQL a un plan d’exécution physique passe par deux étapes:
A) La requête SQL est traduite à l’aide des opérateurs d’algèbre en plusieurs plans d’exécution
logiques (assez abstraits pour l’exécution).
• Sous-étape 3 : Vérification du pool partagé → Si la requête est déjà en cache (Soft Parsing),
elle est exécutée directement. Sinon, elle passe par l'optimiseur (Hard Parsing).
• Sous-étape 6 : Exécution → Lecture des blocs de données en cache ou sur disque. Pour les
mises à jour (LMD), Oracle gère aussi le redo log et les blocs d’annulation.
Index
Un index est une structure de données qui représente un objet dans un schéma de base
de données. Il contient une entrée pour chaque valeur présente dans la colonne indexée,
permettant un accès rapide aux enregistrements.
L'index dans une base de données améliore les performances des opérations telles que
la recherche, le tri, la jointure et l'agrégation.
Dans Oracle, un index est automatiquement créé pour une clé primaire (PRIMARY KEY)
ou une contrainte d'unicité (UNIQUE) sur une colonne.
• Pour les colonnes souvent utilisées dans des jointures (comme les clés étrangères).
• Pour les colonnes très discriminantes, c'est-à-dire celles dont les valeurs sont peu
répétées dans la base.
• Les index peuvent ralentir les performances lors des mises à jour, car il est nécessaire de
mettre à jour les index en même temps que les données.
• Les index augmentent la taille de la base de données, et leur volume peut devenir
significatif.
Arbre équilibré (B-Tree) : l'index par défaut dans Oracle. Il se compose des éléments suivants :
• Feuilles : Contiennent à la fois les clés et les ROWID (adresses vers les blocs
d'enregistrements).
L'arbre est parcouru de gauche à droite, en commençant par la racine, en passant par les
branches, puis en atteignant les feuilles.
Le niveau le plus bas, appelé niveau des feuilles, contient des entrées d'index sous forme de
paires clé/ROWID, permettant d'accéder directement à un bloc d'enregistrement.
Un index unique est créé automatiquement lorsqu'une contrainte UNIQUE est ajoutée à une
colonne. Il garantit l'unicité des valeurs dans la colonne et est de type B-tree. Il peut aussi être
créé manuellement.
Un index inversé est aussi un B-tree, mais il parcourt l'arbre de droite à gauche. Il est utilisé pour
rechercher les valeurs les plus élevées efficacement.
Index composé (composite Index) : est un index qui s'applique sur plusieurs colonnes. Il est
ordonné d'abord par la première colonne, puis par la deuxième, et ainsi de suite. L'ordre des
colonnes est important, il est préférable de commencer par celle avec la plus haute cardinalité
(plus de valeurs distinctes).
Un Bitmap Index est utilisé lorsque le nombre de valeurs distinctes dans une colonne est faible
par rapport au nombre total d'enregistrements (par exemple, pour une colonne gender). Il peut
être simple ou composé et convertit les ROWID en bitmaps. Des opérations AND et OR sont
effectuées sur ces bitmaps avant de les reconvertir en ROWID. Il est efficace pour des tables en
lecture seule ou peu mises à jour, et consomme moins d'espace que les index B-tree.
Un index basé sur une fonction permet de créer un index sur une fonction ou une expression
appliquée à une colonne. Si une fonction est utilisée sur une colonne indexée, l'index classique
ne sera pas utilisé. Par exemple, pour une requête utilisant LOWER(email), un index classique sur
email ne suffira pas.donc il faut créer un index sur la fonction, comme LOWER(email) :
Il est également possible de créer un index sur une expression, par exemple :
Les tables organisées par index (IOT) stockent les clés primaires et les données de colonnes
non-clés dans la même structure B-Tree, éliminant ainsi la nécessité de conserver les ROWID.
Cela permet un accès plus rapide aux données via la clé primaire, car les données et l'index sont
dans la même structure, évitant ainsi une lecture séparée de l'index et des données.
L'IOT est particulièrement adapté aux petites tables où les recherches sont principalement
effectuées sur la clé primaire et où il y a peu de mises à jour.
Syntaxe :
CREATE TABLE table_name (id_name INT PRIMARY KEY, column1, ...) ORGANIZATION INDEX
INCLUDING column1, column2, ...;
La reconstruction d'un index est nécessaire lorsque l'index devient fragmenté à cause des
insertions, modifications et suppressions de données. La fragmentation peut ralentir les
performances des requêtes. La reconstruction supprime l'index existant et en crée un nouveau,
ce qui élimine la fragmentation et réorganise les données.
Pendant la reconstruction, des verrous sont placés sur l'index, empêchant l'accès à celui-
ci. La reconstruction doit être effectuée régulièrement pour maintenir des bonnes performances,
de préférence la nuit ou pendant les week-ends.
L'option ONLINE permet de maintenir l'accès à la table pour les opérations DML
(insertion, mise à jour, suppression) et partitionnement pendant la reconstruction.
Full Index Scan : Utilisée lorsque les colonnes peuvent être directement sélectionnées de l'index
(par exemple, pour un index composé ou une Table Organisée par Index - IOT).
Fast Full Index Scan : Choisie lorsque les colonnes sélectionnées font partie de l'index et qu'au
moins une de ces colonnes à la contrainte NOT NULL. Elle permet d'accéder directement aux
données de l'index, sans accéder à la table.
Index Range Scan : Utilisée lorsque la condition sur la colonne indexée porte sur un ensemble
de valeurs, comme les opérateurs >, >=, <, <=, BETWEEN, ou l'opérateur = dans le cas d'un index
non-unique.
Index Unique Scan : Utilisée lorsque l'index est unique (comme une clé primaire).
Index Skip Scan : Utilisée lorsqu'une condition est appliquée à une colonne qui fait partie d'un
index mais qui n'est pas la première colonne de cet index. La première colonne de l'index est
ignorée.
FULL SCAN : utilisée lorsque Il n'y a pas d'index sur les colonnes sélectionnées ou La clause
WHERE ne contient pas de conditions, ou les conditions sont faites sur des colonnes non
indexées aussi Oracle peut aussi choisir un FULL SCAN si cela est jugé plus performant, par
exemple lorsque la requête retourne une grande partie ou la totalité des données, ou si les
données sont physiquement mal ordonnées ou contiennent beaucoup d'espace libre.
BY INDEX ROWID : Cette méthode est choisie lorsqu'un index est utilisé. Pour chaque ligne de
l'index dont les colonnes correspondent aux conditions de sélection, un accès à la table est
effectué en utilisant le ROWID.
Méthodes de Jointure
Nested Loops : Utilisée lorsque les tables à joindre sont petites. La recherche dans la table
interne doit être supporté par index. Moins performant que les jointures hash et Sort Merge.
Fonctionne mieux si la table externe est plus petite et que la table interne a un index hautement
sélectif sur la clé de jointure de la table externe.
Hash Join : Utilisée lorsque les tables à joindre sont grandes et il y a un prédicat de jointure
d'égalité. Elle fonctionne en créant une table de hachage pour une des tables et en cherchant
ensuite les correspondances dans l'autre table
Sort Merge Join : adapté lorsque les tables à joindre sont grandes et qu'un prédicat de jointure de
non-égalité est appliqué (par exemple, avec des opérateurs comme > ou <). Cette méthode
devient encore plus efficace si les tables sont déjà triées sur les colonnes utilisées pour la
jointure. Elle est utile lorsque la majorité des données des deux tables doit être incluse dans le
résultat, ou lorsqu'il n'y a pas d'index disponibles dans la table interne .
Composants de l’optimiseur
Le Query Transformer évalue si la requête doit être modifiée pour générer un meilleur plan
d'exécution,
L'Estimator estime le coût de chaque plan en se basant sur les statistiques du dictionnaire de
données.
2. Cardinalité : nombre estimé de lignes renvoyées par chaque opération dans le plan
d'exécution, calculée comme le nombre total de lignes divisé par le nombre de valeurs
distinctes (NDV).
3. Coût : mesure numérique qui reflète l’utilisation des ressources pour un plan, prenant en
compte les E/S disque, l’utilisation du processeur et la taille de la mémoire.
Graphique : Utilisation de SQL Developer (en appuyant sur F10) pour visualiser le plan
d'exécution sous forme graphique.
Dbms_xplan.display_awr(sql_id) : Affiche le plan d'exécution d'un Top SQL stocké dans les vues
historiques d'AWR, où sql_id peut être obtenu depuis un rapport AWR.
Génération :
EXPLAIN PLAN [SET STATEMENT_ID='id de requête'] [INTO Nom2Table] FOR instruction SQL;
L'instruction SQL peut être un SELECT, INSERT, UPDATE, DELETE, CREATE TABLE, CREATE INDEX,
ALTER INDEX, etc.
Affichage :
Le format d'affichage du plan d'exécution peut être spécifié avec l'option format dans la fonction
dbms_xplan.display(format => 'format_option'). Voici les différentes options disponibles :
1. BASIC : Affiche les informations minimales du plan, telles que l'ID d'opération, le nom de
l'opération et l'objet de l'opération.
2. TYPICAL : Valeur par défaut. Affiche les informations essentielles du plan, comme l'ID
d'opération, le nom, l'objet, le nombre de lignes, le nombre d'octets et le coût de
l'optimiseur. Les informations sur le parallélisme et les prédicats sont affichés si elles
sont applicables.
3. SERIAL : Comme TYPICAL, mais sans afficher les informations sur le parallélisme, même
si l'opération s'exécute en parallèle.
4. ALL : Affiche un niveau détaillé avec des informations supplémentaires telles que
PROJECTION, ALIAS et des informations sur le REMOTE SQL si l'opération est distribuée.
Dbms_xplan.display_cursor
La comparaison permet de savoir est ce que l’optimiseur Oracle a effectué une bonne estimation
des cardinalités des opérations du plan ou non. C’est une technique rapide de commencer le
tuning de la requête.
Statistiques
Oracle collecte les statistiques automatiquement pour tous les objets de base de
données dont les statistiques sont manquantes ou dont les statistiques sont obsolètes grâce à
un job qui s’exécute (de 22h à 02h tous les jours de la semaine et de 06h à 02 les weekends).
La collecte des statistiques permettent de mettre à jour les vues statiques du dictionnaire
USER ou DBA tels que: USER_TAB_STATISTICS, USER_IND_STATISTICS, etc.
EXEC DBMS_STATS.GATHER_TABLE_STATS(
);
EXEC DBMS_STATS.GATHER_INDEX_STATS(
);
EXEC DBMS_STATS.GATHER_SCHEMA_STATS(
);
Les statistiques peuvent être affichées via les vues statiques mentionnées précédemment
(USER_TAB_STATISTICS, USER_IND_STATISTICS, etc.).
Pour supprimer les statistiques d’une table, un index ou un schéma, les procédures PL/SQL
peuvent respectivement être utilisées:
• DBMS_STATS.DELETE_TABLE_STATS
• DBMS_STATS.DELETE_INDEX_STATS
• DBMS_STATS.DELETE_SCHEMA_STATS
o Un faible taux d’occupation des blocs peut être dû à des valeurs inadaptées de
PCTFREE et PCTUSED ou à une suppression massive de données. Cela entraîne
une sous-utilisation des ressources allouées et une fragmentation du stockage.
o Si le nombre de blocs de feuilles dans l'index augmente, cela peut entraîner une
surcharge des E/S. La cause principale est la fragmentation de l'index due à des
insertions et suppressions fréquentes.
o Une profondeur d'index (BLEVEL) trop élevée peut ralentir les performances de
recherche, souvent à cause d'un PCTFREE mal adapté ou d’un index très volatil.
Solutions :
Statistiques et Histogrammes
Par défaut, l'optimiseur suppose une distribution uniforme des lignes sur les différentes
valeurs d'une colonne. Pour les colonnes contenant des données asymétriques (une distribution
non uniforme des données au sein de la colonne), un histogramme permet à l'optimiseur de
générer des estimations de cardinalité précises pour les prédicats de filtre et de jointure qui
impliquent ces colonnes. Donc, un histogramme est un type de statistiques qui permet à
l’optimiseur d’analyser la distribution des données et estimer correctement la cardinalité.
BEGIN
dbms_stats.delete_column_stats(
);
END;
Statistiques dynamiques
• Utilisation : Si certaines tables de la requête n'ont pas de statistiques, l'optimiseur utilise les
statistiques dynamiques pour collecter des données de base avant d'optimiser la requête.
• Limites : Ces statistiques sont moins complètes et de moins bonne qualité que celles
collectées avec le package DBMS_STATS. Ce compromis est fait pour minimiser l'impact sur
le temps de compilation de la requête.
Synthèse
Hint
Les hints en SQL sont des instructions ou des commentaires adressés à l'optimiseur de
la base de données, l'incitant à choisir un plan d'exécution différent pour une requête SQL. Elles
sont utilisées principalement lorsque les statistiques sont à jour mais que l'optimiseur ne choisit
toujours pas le plan optimal.
Points clés :
2. Utilisation : À utiliser en dernier recours, lorsque les statistiques sont correctes mais que
la requête ne suit pas un plan optimal.
3. Syntaxe : Un hint est placé dans un commentaire et suit le mot-clé de la requête (SELECT,
UPDATE, INSERT, MERGE, DELETE).
4. Types de requêtes : Les hints sont utilisés avec des requêtes SELECT, UPDATE, INSERT,
MERGE, et DELETE.
Exemples de hints :
• ALL_ROWS : Optimise la requête pour une meilleure performance globale, pas seulement
pour les premières lignes.
SELECT /*+ USE_MERGE(emp dept) */ FROM emp, dept WHERE emp.deptno = dept.deptno;
INSERT /*+ APPEND */ INTO mytab SELECT /*+ CACHE (e) */ FROM emp e;
Le SQL Tuning (Réglage SQL) est un processus itératif visant à améliorer les performances des
requêtes SQL pour atteindre des objectifs spécifiques et mesurables.
Types de Tuning :
1. Tuning proactif : On utilise régulièrement des outils comme SQL Tuning Advisor pour
identifier les opportunités d'amélioration des performances des requêtes SQL.
2. Tuning réactif : On intervient pour résoudre un problème spécifique lié à une requête SQL
rencontrée par un utilisateur.
Outils de tuning
1. Un outil est automatisé si la base de données elle-même peut fournir un diagnostic, des
conseils ou des actions correctives. Exemple d’outils: ADDM, SQL Tuning Advisor,
Tous les outils de tuning dépendent des vues dynamiques de performances, des statistiques
et des métriques que l'instance de base de données collecte.
Utilisant un outil automatisé ou manuel, SQL Tuning comporte les tâches suivantes:
• Mauvaise conception des instructions SQL : Par exemple, des jointures cartésiennes,
l'utilisation de hints pour forcer une grande table en tant que table principale dans une
jointure, ou des sous-requêtes exécutées pour chaque ligne.
• Choix des plans d'exécution sous-optimaux : Lorsque l'optimiseur sélectionne un plan
inefficace, comme une analyse complète de table au lieu d'un index pour une requête à
faible sélectivité.
• Structures d'accès SQL manquantes : L'absence d'index ou de vues matérialisées peut
mener à des performances sous-optimales.
• Statistiques d'optimisation obsolètes : Des statistiques non mises à jour peuvent
entraîner des décisions erronées par l'optimiseur.
• Problèmes matériels : Des problèmes liés à la mémoire, aux entrées/sorties (E/S), ou
au processeur peuvent également affecter les performances.
Tuning manuel
Le tuning manuel SQL utilise plusieurs outils pour diagnostiquer et optimiser les requêtes :
1. Plans d'exécution : Ils sont essentiels pour le diagnostic. Différentes méthodes pour les
afficher incluent :
o DBMS_XPLAN : Affiche les plans d'exécution générés par la commande Explain for.
o V$SQL_PLAN : Vue contenant des informations sur les plans d'exécution des requêtes
exécutées.
3. SQL Trace Facility et TKPROF : Ces outils permettent d'évaluer l'efficacité des
instructions SQL. SQL Trace crée des fichiers de trace détaillant les performances, et
TKPROF formate ces fichiers pour générer des rapports.
o Le fichier de trace contient des informations sur les analyses, les exécutions, les
lectures, le CPU, etc.
TKPROF
TKPROF est un programme qui formate le contenu des fichiers de trace SQL, les rendant lisibles.
Il peut aussi générer des plans d'exécution et des scripts SQL pour enregistrer les statistiques
dans la base de données.
3. AGGREGATE : Par défaut, TKPROF agrège plusieurs utilisateurs du même texte SQL. Si
AGGREGATE = NO est défini, il ne les agrège pas.
5. TABLE : Spécifie la table où TKPROF place temporairement les plans d'exécution avant de
les écrire dans le fichier de sortie.
6. INSERT : Crée un script SQL pour stocker les statistiques du fichier de trace dans la base
de données.
PRINT : Liste les 1ers instructions SQL triées par nombre d'occurrences dans le fichier de sortie.
Exemple : TKPROF ora53269.trc ora 53269.prf SORT = (PRSDSK, EXEDSK, FCHDSK) PRINT = 10
Dans cet exemple, l'instruction suivante imprimera les dix instructions du fichier de trace qui ont
généré le plus d'E/S physiques.
Rapport TKPROF
Le rapport TKPROF est généré après l'exécution de la commande TKPROF sur un fichier
de trace SQL. Il contient 3 sections principales : l'en-tête, le corps du rapport TKPROF et les
appels récursifs.
1. Option Explain :
Lorsque l'option EXPLAIN est utilisée, TKPROF génère également les plans d'exécution pour
chaque requête SQL tracée. Par exemple, la commande suivante :
2. Structure du rapport :
• Corps du rapport TKPROF : Détails sur les requêtes SQL exécutées, y compris les plans
d'exécution et les statistiques de performance.
• Appels récursifs : Certaines instructions SQL génèrent des appels récursifs, par
exemple, lors de l'ajout de nouvelles lignes dans une table ou lorsque des informations du
dictionnaire de données doivent être récupérées depuis le disque.
3. Appels récursifs :
Les appels récursifs sont générés lorsqu'Oracle doit émettre des instructions supplémentaires
pour compléter une requête. Par exemple :
Lorsque des appels récursifs sont présents dans le fichier de trace, TKPROF inclut ces
statistiques dans le rapport et les marque clairement, ce qui permet d'analyser leur impact sur
les performances.
Le SQL Tuning Advisor est un outil qui analyse les requêtes SQL et fournit des
recommandations pour les optimiser. Il peut traiter une ou plusieurs requêtes et utilise
l'AutomaticTuning Optimizer pour appliquer des réglages afin d'améliorer les performances des
requêtes.
Fonctionnement :
• Recommandations : Le SQL Tuning Advisor propose des actions spécifiques pour améliorer
les performances des requêtes SQL, telles que :
Ces recommandations sont fournies dans un rapport détaillé, avec les avantages attendus.
Privilèges nécessaires :
Pour que les utilisateurs non-sysdba utilisent SQL Tuning Advisor, des privilèges spécifiques
doivent leur être attribués :
SQL Profile
Un SQL profile est un objet stocké dans le dictionnaire de la base de données, conçu pour
corriger les estimations d'optimiseur sous-optimales identifiées lors du SQL Tuning automatique.
Il est créé par l'Automatic Tuning Optimizer en utilisant les données collectées lors de
l'exécution réelle des requêtes. Cela permet d'améliorer la précision des estimations de
cardinalité et de sélectivité.
Le SQL Access Advisor est un outil qui aide à améliorer les performances SQL en
recommandant la création, la suppression ou la conservation d'index, de vues matérialisées,
de journaux de vues matérialisées ou de partitions. Il est essentiel pour optimiser les requêtes
complexes et gourmandes en ressources. Pour fonctionner, il nécessite une charge de travail
composée de requêtes SQL et de leurs statistiques, provenant de la Zone SQL partagée ou d'un
Ensemble de réglages SQL (STS).
Le SQL Tuning Set (STS) est un ensemble de requêtes SQL et des informations associées,
permettant d'appliquer des outils de tuning comme le SQL Tuning Advisor et le SQL Access
Advisor. Il regroupe des requêtes stockées dans le SHARED POOL, AWR ou d'autres sets. Pour
créer un SQL Tuning Set, vous pouvez utiliser la commande suivante :
SQL> begin
dbms_sqltune.create_sqlset(sqlset_name=>'Elbeggar_STS',
end;
Ajouter des requêtes à SQL Tuning Set Par exemple, le programme PL/SQL suivant remplit le STS
précédent avec toutes les instructions de cache de curseur qui appartiennent au schéma hr :
SQL> DECLARE
c_sqlarea_cursor DBMS_SQLSET.SQLSET_CURSOR;
BEGIN
SELECT VALUE(p)
FROM TABLE(
DBMS_SQLSET.SELECT_CURSOR_CACHE(
) p;
DBMS_SQLSET.LOAD_SQLSET (
);
END;
Pour lancer le SQL Tuning Advisor avec un SQL Tuning Set (STS), vous pouvez créer une
tâche de maintenance avec le code suivant :
SQL> DECLARE
l_sql_tune_task_id VARCHAR2(100);
BEGIN
l_sql_tune_task_id := DBMS_SQLTUNE.create_tuning_task (
description => 'Tuning task for an SQL tuning set.' -- Description de la tâche
);
END;
La dégradation des performances due aux changements des plans d'exécution dans
Oracle peut être causée par des facteurs tels que la mise à niveau d'Oracle Optimizer, la mise à
jour des statistiques, des changements dans le schéma ou les paramètres d'optimisation. Pour
stabiliser les performances, il est recommandé d'utiliser des Plan Baseline pour forcer
l’utilisation d’un plan spécifique, de maintenir des statistiques à jour avec DBMS_STATS, et de
vérifier les impacts des modifications du schéma sur les plans d'exécution.