Initiation à l'optimisation de requêtes SQL sous ORACLE

par Jean-Philippe GUILLOUX

Date de publication : 21/12/2008 Dernière mise à jour : 25/12/2008

Les bases de données sont un élément essentiel lorsqu'il s'agit de la persistance de l'information. Oracle est un acteur majeur et beaucoup d'applications d'entreprise reposent sur leur SGBD. L'optimisation de la base en elle même est souvent du ressort du DBA. Toutefois, le développeur qui écrit la requête connaît souvent mieux que le DBA la logique métier qui entoure un projet et sera ainsi mieux à même d"optimiser ses requêtes. L'objectif de ce document est d'introduire la notion d'optimisation de requête et les bases nécéssaires pour comprendre comment améliorer les performances de ses interrogations.

Initiation à l'optimisation de requêtes SQL sous ORACLE par Jean-Philippe GUILLOUX

I - Objectif de ce document I-A - Introduction I-B - Public ciblé et pré-requis I-C - Mise en garde - Limites II - Plan d'exécution, optimiseur, coût, chemin d'accès et statistiques II-A - Chemin d'accès II-B - Plan d'exécution II-C - Trouver le meilleur chemin ? On a un GPS ? (L'optimisteur) II-D - Les statistiques II-E - Les hints : "je suis grand c'est moi qui gère" II-F - Et concrètement comment je le sais le plan d'éxecution pour ma requête ? III - Les chemins d'accès IV - Les index IV-A - Définition - Avantages IV-B - Les différents types d'index IV-C - Les index composés :quelques règles IV-D - Les balayages d'index IV-E - Inconvénients et limites des index IV-E a - Une grosse limite: les fonctions IV-E b - Trop d'index tue l'index IV-F - Quand l'index se substitue à la table ... V - Les tables organisées en index VI - Clefs etrangères et index VII - Mais pourquoi Oracle n'utilise t'il pas mon index ? (le méchant) VII-A - La fonction ... VII-B - La fonction qu'on ne voit pas ... VII-C - Les stats VII-D - Ce n'est pas le meilleur chemin VIII - Tables en cache IX - Vues matérialisées X - Les index ne font pas tout ... XI - En plus de l'optimisation de requête XII - Conclusion XIII - Remerciements et liens

-2Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
http://jpg.developpez.com/oracle/tuning/

Limites Cet article ne se veut en aucun cas un guide exhaustif du tuning sous Oracle ! Il n'est que la retranscription écrite de connaissances que j'ai pu acquérir.Public ciblé et pré-requis Cet article s'adresse aux développeurs et à toute personne sachant exécuter des ordres SQL simples.developpez.Mise en garde .. Il est fréquent qu'une requête mal écrite coûte 10 fois plus de temps et de ressources qu'elle ne le devrait. Je ne détaillerai ici que les éléments concernant vraiment les développeurs et omettrait parfois par souci de simplification d'expliquer des notions pointues . cet article se veut une initiation à des opérations simples qui permettent d'améliorer les performances. Le tuning de base de données est une chose complexe. I-B . ici dans le cas d'Oracle.Objectif de ce document I-A . http://jpg. modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur. I-C .. le DBA ne peut pas connaître la logique métier de toutes ses bases ni passer réécrire les requêtes de chacun des développeurs.Initiation à l'optimisation de requêtes SQL sous ORACLE par Jean-Philippe GUILLOUX I . Aucune connaissance DBA ou autre n'est requise. Lorsque l'application n'est pas seule sur le serveur de base de données. La conception d'applications performantes passera nécéssairement par la connaissance des différents éléments permettant d'avoir des bases répondant aux besoins et évolutives.com et reste la propriété exclusive de son auteur. désirant rapidement améliorer les performances de ses requêtes et la conception de sa base.Introduction L'optimisation des bases de données est souvent perçue comme étant une tâche du DBA. les ralentissements ou la surconsommation de ressource peuvent s'avérer gênants non seulement pour l'application mais aussi les autres projets/ applications partageant les ressources. cependant sur de gros volumes de données et un grand nombre de bases. La copie. des jointures simples.developpez. -3Ce document est issu de http://www. Pour que les développeurs puissent écrire des requêtes efficaces il leur est nécéssaire de connaître quelques uns des mécanismes mis en oeuvre lors de l'exécution de leurs requêtes.com/oracle/tuning/ .

. chemin d'accès et statistiques II-A . Citons parmi celles-ci par exemple le "parcours complet de table" ou "full table scan".. De la même manière qu'il y a plusieurs manières de se rendre de Paris à Tokyo. accès disques. Lire sur un disque c'est lent. Oracle dispose de plusieurs solutions que nous expliquerons sous peu..) qui le composent. (promis.. Evidemment le terme "chemin le plus intéressant" est assez subjectif (et règlable par le DBA dans le cas d'Oracle) mais on demande le plus souvent à Oracle d'utiliser le chemin qu'il estime avoir le meilleur "coût" (cost-based). . Pour Oracle ces données sur les objets qu'il contient (méta-données) s'appellent les statistiques. bref. Pour en savoir plus sur le calcul des stats sur vos bases. coût.Plan d'exécution Il est souvent nécéssaire sur des requêtes d'interroger une ou plusieurs tables qui feront donc l'objet d'un ou plusieurs chemins d'accès.) pour un plan donné.Trouver le meilleur chemin ? On a un GPS ? (L'optimisteur) Trouver le chemin le plus intéressant pour accéder aux données. devoir effectuer un tri de données sur le disque s'avère souvent extrêmement coûteux.. posséder des données sur les trajets..Chemin d'accès Un des objectifs des bases de données est de stocker l'information tout en l'organisant de manière à pouvoir y accéder rapidement. modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur. L'ensemble des chemins d'accès utilisés pour une requête a pour nom "Plan d'exécution".). on va expliquer tout cela après. les risques d'embouteillage . le "parcours d'index" ou "Index range scan" . II-B . La copie..Les statistiques L'optimiseur choisit nous disions . c'est le boulot de l'optimiseur Oracle. Pire encore.com et reste la propriété exclusive de son auteur.. Normalement. II-D . II-C . elles sont en général calculées automatiquement / périodiquement (Oracle 10G) ou manuellement(10G et avant .developpez... il y a plusieurs manières d'accéder à l'information.. mémoire . demandez à votre DBA. On peut comparer le plan d'exécution à un itinéraire complet entre deux villes et le chemin d'accès aux indications (vous savez le "tourner à droite". Le coût tient compte de l'utilisation des ressources (CPU. Calculer des stats se fait en lançant une requête "ANALYZE TABLE matable COMPUTE STATISTICS.. L'élément à mon avis le plus important est le nombre d'I/O Disque que nécéssite la requête.." par exemple ou mieux en utilisant le package dbms_stats comme ici: -4Ce document est issu de http://www. http://jpg... d'accord mais comment il sait par où il faut passer lui ? Pour choisir le bon chemin entre deux villes il faut savoir les distances.. optimiseur.Plan d'exécution.Initiation à l'optimisation de requêtes SQL sous ORACLE par Jean-Philippe GUILLOUX II . Pour accéder à une ligne donnée d'une table.developpez.. Les statistiques permettent à l'optimiseur d'estimer le coût d'accès aux données.). Ces différentes alternatives pour l'accès aux données sont tout simplement appelées "chemin d'accès"..com/oracle/tuning/ .

0 .Initiation à l'optimisation de requêtes SQL sous ORACLE par Jean-Philippe GUILLOUX EXEC DBMS_STATS. ConnectÚ Ó : Oracle Database 10g Express Edition Release 10.. argl ! EXEC DBMS_STATS.gather_index_stats('SCOTT'.developpez.com et reste la propriété exclusive de son auteur.0.com/oracle/tuning/ . Beaucoup des éléments que je décrirai par la suite feront l'objet de hints possibles. 'EMPLOYEES').last_name from employees where last_name like 'T%'. 19 17:40:22 2008 Copyright (c) 1982. du moins à notre goût.Et concrètement comment je le sais le plan d'éxecution pour ma requête ? Pas mal d'outils (SQL Developer de Oracle [gratuit] et TOAD) ont un petit bouton magique qui permet de voir le plan.gather_schema_stats('SCOTT'. FIRST_NAME -------------------Jonathon Winston Sigal Peter Oliver LAST_NAME ------------------------Taylor Taylor Tobias Tucker Tuvault -5Ce document est issu de http://www.2. II-E . Le web est plein d'indications sur la chose.. estimate_percent => 15). // pour une table EXEC DBMS_STATS. estimate_percent => 15). 'EMPLOYEES'. 2005. // pour toute la base .gather_schema_stats('SCOTT'). plusieurs manières s'offrent à vous. Oracle. Oracle le suivra si c'est possible et l'ignorera sinon.developpez. // pour un index EXEC DBMS_STATS. La copie. Personnellement je ne recommande pas l'utilisation des hints tant qu'il n'y a pas de souci.Production on Mer. Sous SQLPlus.2.. L'utilisation des hints suppose donc de bonnes connaissances dans le domaine et de Oracle.gather_database_stats(estimate_percent => 15).gather_table_stats('SCOTT'. // idem avec 15% . // collecte pour le schéma SCOTT EXEC DBMS_STATS. modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.gather_database_stats. Quand la volumétrie ou d'autres éléments changent le hint peut devenir caduque et contre-performant. Nov.0 .Production SQL> select first_name. // pour la base. http://jpg.1.gather_table_stats('SCOTT'.gather_index_stats('SCOTT'. // idem avec 15% d'achantillon EXEC DBMS_STATS. Le plus simple à mon goût est le mode autotrace: sqlplus hr/hr SQL*Plus: Release 10. estimate_percent => 15). 'EMPLOYEES_PK').0. avec un échantillon de 15% EXEC DBMS_STATS. All rights reserved. Dans certains cas l'optimiseur peut ne pas prendre le meilleur chemin.Les hints : "je suis grand c'est moi qui gère" Les hints ou suggestions sont les instructions que nous pouvons insérer dans nos ordres SQL pour influencer l'optimiseur. II-F .. On peut alors l'influencer en insérant dans l'ordre SQL un hint se présentant comme ceci : /*+ MONHINT */. L'inconvénient des hints est le fait qu'ils sont écrits en dur et donc inévitablement figés. EXEC DBMS_STATS.1. Je tacherai d'indiquer en vert ces hints au fur et à mesure. 'EMPLOYEES_PK'.

modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.access("LAST_NAME" LIKE 'T%') filter("LAST_NAME" LIKE 'T%') Statistiques ---------------------------------------------------------0 recursive calls 0 db block gets 2 consistent gets 0 physical reads 0 redo size 595 bytes sent via SQL*Net to client 384 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 5 rows processed SQL> Le plan est à lire comme suit: Oracle a utilisé un scan (on y revient plus tard) sur l'index "EMP_NAME_IX" et c'est tout. SQL> select first_name.Initiation à l'optimisation de requêtes SQL sous ORACLE par Jean-Philippe GUILLOUX Activons le autotrace: SQL> set autotrace on. SQL> select plan_table_output from table(dbms_xplan. Une autre solution est de faire un EXPLAIN PLAN sur une commande: SQL> explain plan for (select * from employees where last_name like 'T%').developpez. FIRST_NAME -------------------Jonathon Winston Sigal Peter Oliver LAST_NAME ------------------------Taylor Taylor Tobias Tucker Tuvault Plan d'exÚcution ---------------------------------------------------------Plan hash value: 3085132068 -------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 5 | 75 | 1 (0)| 00:00:01 | |* 1 | INDEX RANGE SCAN| EMP_NAME_IX | 5 | 75 | 1 (0)| 00:00:01 | -------------------------------------------------------------------------------Predicate Information (identified by operation id): --------------------------------------------------1 . La copie.. ExplicitÚ. Vos pires ennemis sont dans les statistiques . Tous les physical reads seront à réduire et les sorts (disk) ou tris sur le disque également.. http://jpg.display()).last_name from employees where last_name like 'T%'.com et reste la propriété exclusive de son auteur. PLAN_TABLE_OUTPUT ------------------------------------------------------------------------------------------Plan hash value: 2077747057 ------------------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 5 | 340 | 2 (0)| 00:00:01 | | 1 | TABLE ACCESS BY INDEX ROWID| EMPLOYEES | 5 | 340 | 2 (0)| 00:00:01 | -6Ce document est issu de http://www.developpez.com/oracle/tuning/ .

ExplicitÚ. Nb: Si Oracle vous insulte avec un message "SP2-0618: Impossible de trouver l'identificateur de session.. Ici on peut lire dans le plan que Oracle a effectué un scan sur l'index EMP_NAME_IX puis a accédé à la table EMPLOYEES via les ROWID (on décodera tout cela après). SP2-0611: Erreur lors de l'activation de l'état STATISTICS" lorsque vous voulez activer le autotrace demandez à votre dba de lancer une commande qui vous donnera le droit de le faire: "grant plustrace to votreUser.access("LAST_NAME" LIKE 'T%') filter("LAST_NAME" LIKE 'T%') 15 ligne(s) sÚlectionnÚe(s). PLAN_TABLE_OUTPUT -------------------------------------------------------------------------------------------Plan hash value: 2077747057 ------------------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 5 | 340 | 2 (0)| 00:00:01 | | 1 | TABLE ACCESS BY INDEX ROWID| EMPLOYEES | 5 | 340 | 2 (0)| 00:00:01 | |* 2 | INDEX RANGE SCAN | EMP_NAME_IX | 5 | | 1 (0)| 00:00:01 | ------------------------------------------------------------------------------------------Predicate Information (identified by operation id): PLAN_TABLE_OUTPUT --------------------------------------------------------------------------------------------2 . passons donc maintenant à quelques notions sur les index.com/oracle/tuning/ .Initiation à l'optimisation de requêtes SQL sous ORACLE par Jean-Philippe GUILLOUX |* 2 | INDEX RANGE SCAN | EMP_NAME_IX | 5 | | 1 (0)| 00:00:01 | ------------------------------------------------------------------------------------------Predicate Information (identified by operation id): PLAN_TABLE_OUTPUT ------------------------------------------------------------------------------------------2 . La copie.com et reste la propriété exclusive de son auteur.developpez. SQL> select plan_table_output from table(dbms_xplan. -7Ce document est issu de http://www.access("LAST_NAME" LIKE 'T%') filter("LAST_NAME" LIKE 'T%') 15 ligne(s) sÚlectionnée(s).. modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur." Voilà pour ces quelques définitions. Les colonnes cost et time sont précieuses . SQL> explain plan for (select * from employees where last_name like 'T%'). Le rôle PLUSTRACE doit être activé. http://jpg.display()).developpez.

. mais pas toujours. Cette lecture donne généralement lieu à des accès par rowid aux lignes concernées dans la table.Les chemins d'accès Je vais ici passer assez vite sur les différents modes d'accès aux données . C'est très rapide mais suppose de connaître le ROWID .com/oracle/tuning/ . étant donné que toute la table est lue.. Oracle accède aux lignes directement par leur ROWID (identifiant interne) dans la table. Les voici: • Parcours complet de table ou Full Table Scan: Là c'est simple on parcourt toute la table. • • -8Ce document est issu de http://www. La copie.. Je reviendrai sur les différentes méthodes de balayage dans la partie sur les index Accès par ROWID ou Table Access by ROWID: Le ROWID ou Id de ligne est un identifiant permettant d'acceder le plus rapidement possible à une ligne.developpez.Initiation à l'optimisation de requêtes SQL sous ORACLE par Jean-Philippe GUILLOUX III .. comme on le verra. on est donc passé par une autre étape avant typiquement un INDEX RANGE SCAN.com et reste la propriété exclusive de son auteur. modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur. http://jpg. Ce mode est couteux sur de grosses tables car il génère beaucoup d'accès disque.developpez. on pourrait aller très loin dans la technique mais cela sortirait de l'objectif que je me suis ici fixé. Parcours (ou balayage) d'index Un index est parcouru à la recherche des valeurs. En l'absence d'index approprié à la recherche c'est ce qu'Oracle fait.

ce type d'index est particulièrement efficace lorsque le nombre de valeurs est petit ainsi que pour les opérations AND et OR. http://jpg. 001 pour Monsieur. La copie.PRENOM) cela crée un index en arbre avec les personnes classées par nom puis par prenom .Avantages On peut voir un index comme un glossaire.Les différents types d'index Mettre un index c'est bien. les racines constituées par les valeurs précisées à gauche. si je crée un index avec (NOM.com et reste la propriété exclusive de son auteur. on peut par exemple indexer au sein du même index la date de naissance et le nom de la personne. Un index peut être basé sur une ou plusieurs valeurs . Prenons en exemple le champ "civilité" de ma table individus.Définition .. Comme son nom l'indique l'index b-tree est organisé en arbre. Oracle gère plusieurs types d'index. on parle alors d'index composé ou composite. modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur. Exemple : Créer un index sur le champ "date de naissance" d'un individu permettra de retrouver rapidement tous les individus nés à une date donnée. Si on effectue souvent la recherche avec date de naissance et nom de la personne cet index sera probablement intéressant. un sommaire. Par exemple l'index basé sur le champ (numero) de téléphone ne sera pas utilisable pour un "where telephone is not null". Avoir un glossaire basé sur le bon critère vous permet d'accéder rapidement à la page du livre traitant du sujet désiré. 010 pour Mademoiselle. un index base sur la bonne valeur permettra à Oracle de retrouver rapidement l'ensemble de lignes concernées par la requête.Les index IV-A . L'index (nom. Là je vais illustrer par un exemple cela vaut mieux . 'Mademoiselle' et NULL (vide). si elles sont seules. En résumé une valeur nulle peut exister dans l'index à condition qu'elle soit associée à une valeur non nulle... Ce champ contient un nombre très limité de valeurs possibles: 'Monsieur' .. Attention: les valeurs NULL ne sont pas indexées dans un index. L'index permet donc à Oracle de trouver les lignes de la table qui correspondent à la requête. 'Madame' . telephone) sera ainsi utilisable si nom n'est pas nul. L'index représente souvent le premier niveau d'optimisation d'une requête : positionner un index là où il faut permet assez souvent de diminuer grandement le coût d'accès à une table (voir les chemins d'accès).developpez.PRENOM) via la commande create index monIndex on individus(NOM. Par contre un index basé sur deux colonnes dont une ne sera pas nulle sera utilisable.Initiation à l'optimisation de requêtes SQL sous ORACLE par Jean-Philippe GUILLOUX IV . IV-B .com/oracle/tuning/ . 100 pour Madame -9Ce document est issu de http://www. De même. composé d'autant de bits que de possibilités de valeurs de l'index. connaître les types d'index permet d'aller plus loin.. Les voici: • B-tree: Les index b-tree sont le type d'index par défaut quand on ne précise rien.. qui ont chacun leurs spécificités et sont plus avantageux dans tel ou tel cas. En clair.developpez. Les valeurs de l'index pourront par exemple être: 000 pour NULL. • Bitmap: Un mot binaire est créé.

Ce type d'index est très performant lorsque le nombre valeur est petit. PRENOM) pourra être utilisé le plus efficacement sur une requête dont la clause ne porterait que sur NOM.. • IV-C . ce type d'index a toutefois un inconvénient... Pour l'utilité on y vient juste après :) Ce type d'index revient donc à précalculer une valeur.com et reste la propriété exclusive de son auteur. Le verrou se fait sur la valeur dans l'index et on se retrouvera lors d'une mise à jour avec un verrou sur toutes les lignes concernées par cette valeur de l'index et ça peut faire beaucoup . La raison de cette inversion provient du fait que les index peuvent devenir un goulot d'étranglement quand un grand nombre d'insertions est fait . par exemple CREATE INDEX monIndex on invidus(nom. Il sera donc intéressant de placer les colonnes les plus interrogés en début d'index. Il est également plus efficace d'avoir les valeurs les plus restrictives en début d'index. IV-D . mais via une opéation moins efficace. simplement pour les comprendre • Le balayage d'intervalle d'index (index range scan): L'index est parcouru pour trouver les valeurs.PRENOM.Les index composés :quelques règles Commme nous l'avons vu les index composés sont des index sur plusieurs valeurs. Les index basés sur des fonctions: là on n'indexe plus un champ mais le résultat d'une opération sur un champ. les index bitmaps provoquent lors des opérations d'écriture des verrous importants qui font qu'ils sont très adaptés aux bases en lecture mais deviennent contre-indiqués dès lors que la base devra subir un nombre important d'insert par exemple... quand vous insérez par exemple beaucoup de valeurs venant d'une séquence. on ne peut y effectuer des "range scan" (parcours d'une partie de l'index) de part sa nature discontinue. supériorité ou infériorité déclenchent généralement ces opérations. les balayages d'index sont une possibilité d'accès. Toutefois.. Seul l'opérateur égalité peut l'utiliser. En cassant la continuité.Les balayages d'index Nous avons vu dans le chapitre sur les chemins d'accès.com/oracle/tuning/ . on crée un index sur UPPER(monChamps) plutôt que sur monChamps.. Nous allons les détailler. Par exemple l'index (NOM. La copie.developpez. Les clauses d'égalité.TELEPHONE) sera toutefois utilisable pour une requête ne contenant qu'une clause sur TELEPHONE. l'index (NOM.. Ces index sont particulièrement efficaces pour des requêtes avec des clauses WHERE complexes. A utiliser en connaissant ses limites.Initiation à l'optimisation de requêtes SQL sous ORACLE par Jean-Philippe GUILLOUX Lors de la recherche Oracle effectuera un simple AND sur la valeur de l'index pour comparer.developpez. c'est le même bloc de l'index qui est alors systématiquement sollicité. Cela peut facilement être gênant. http://jpg. L'index étant ordonné. Ils sont également économiques en stockage. L'index peut servir à effectuer un . des opérations count ou sum . Par exemple. modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur... on enlève cet inconvénient . Une requête portant une partie des champs indexés ne pourra utiliser au mieux l'index que si ces champs sont placés en tête d'index.prenom). Concrètement cet index pourra être utilisé lors d'une clause where monchamp=maValeur mais pas avec une clause where monChamps > maValeur.10 Ce document est issu de http://www. CREATE BITMAP INDEX monIndex ON INDIVIDUS(NOM) • Les index à clefs inversées: là c'est très simple : "1234" deviendra "4321" .

Le balayage à contre-sens (descending index scan): L'index est parcouru à contre sens. En plus clair.developpez.com et reste la propriété exclusive de son auteur. Imaginons maintenant qu'on veuille faire une requête qui ne soit pas sensible à la casse. on obtient le plan d'exécution: . imaginons que je veuille les gens de ta table individus dont le nom est 'MACHIN'. La copie.Initiation à l'optimisation de requêtes SQL sous ORACLE par Jean-Philippe GUILLOUX tri car il est déjà trié. http://jpg. pour Oracle UPPER(monChamp) et monChamp c'est deux choses complètement différentes ! Repartons dans du plus concret. Par contre avec SELECT * from INDVIDUS where nom=UPPER('MACHIN'). Ceci est généralement fait pour un tri. Oracle se basera sur l'index à contre-sens pour son tri. On va donc faire un upper sur notre champ et le comparer à notre paramètre ('MACHIN').Une grosse limite: les fonctions Un index ne peut être utilisé que lorsque la recherche est faite directement sur la valeur indexée elle-même. on obtient le plan d'exécution: TABLE ACCESS FULL TABLE INDVIDUS Cost: 6 Bytes: 540 Cardinality: 2 Et là on dit "argl". Et oui UPPER(NOM) et NOM ce n'est pas la même chose.com/oracle/tuning/ . On sait qu'on va souvent faire une recherche sur ce champ. • • • Le balayage unique (unique index scan): il s'applique lorsque l'index repose sur une colonne possédant une contrainte d'unicité (Unique). donc on va l'indexer. on obtient le plan d'exécution: TABLE ACCESS BY INDEX ROWID TABLE INDVIDUS Cost: 2 Bytes: 270 Cardinality: 1 1 INDEX RANGE SCAN INDEX INDVIDU_NOM Cost: 1 Cardinality: 1 Et donc on passe désormais par notre index :). Par exemple si la première colonne d'un index composé n'est pas mentionnée dans la requête Oracle peut choisir de quand même utiliser l'index et effectuera cette opération.11 Ce document est issu de http://www. SELECT * from INDVIDUS where UPPER(nom)='MACHIN'.Inconvénients et limites des index IV-E a . modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur. Un bel index donc ! et je quand je fais ma requête sur le nom: SELECT * from INDVIDUS where nom='MACHIN'.developpez. IV-E . CREATE INDEX INDVIDU_NOM on INDVIDUS(NOM) COMPUTE STATISTICS. Le balayage par saut (index skip scan): l'index est parcouru en sautant les zones où les clefs ne pourraient pas se trouver.

IV-F . Evidemment pour nous c'est transparent. Reprenons le cas où nous avons un index sur INDVIDU. Une opération d'écriture sur un champ indexé est selon la doc Oracle 3 fois plus lente que sans index. La copie. si l'index nous faisait seulement gagner de la vitesse ce serait trop beau.developpez. Car une sélection trop longue car non indexée solicitera la base de manière excessive..Trop d'index tue l'index "Bon alors l'index ça accélère les selects donc autant en créer plein non ?" Halte là mon ami.I_CANDIDAT_NOM Cost: 1 Bytes: 8 Cardinality: 1 .. modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur. La question "faut-il indexer alors ?" se pose donc et là. Pour notre problème d'index ici présent deux solutions peuvent marcher: • • Si on peut le faire. les index sont en général très intéressants. IS NOT NULL dans une requête vous courrez au FULL TABLE SCAN. Là on constatera que Oracle utilise notre bel index car on compare bien UPPER(nom) à 'MACHIN'..com et reste la propriété exclusive de son auteur. imposer que le champ de la base soit uniquement en majuscule (code. c'est Oracle qui fait le boulot. les NULL. Retenez que quand on peut mettre une valeur par défaut.Initiation à l'optimisation de requêtes SQL sous ORACLE par Jean-Philippe GUILLOUX TABLE ACCESS BY INDEX ROWID TABLE INDVIDUS Cost: 2 Bytes: 270 Cardinality: 1 1 INDEX RANGE SCAN INDEX INDVIDU_NOM Cost: 1 Cardinality: 1 C'est parce que là la fonction est bien appliquée au paramètre et non à notre champ indexé. mais ça a un prix. http://jpg.. Quand on fait un INSERT sur une table avec 4 index cela coute donc 4*3=12 fois plus cher que sans ces index.Quand l'index se substitue à la table .. si l'index ne faisait que tout accélérer pourquoi est-ce qu'on en aurait pas créés de tout partout ? Evidemment.) afin de ne pas avoir à utiliser UPPER et donc arriver à NOM='MACHIN' dans la requête. Dès qu'il y aura un IS NULL. Il arrive que parfois notre interrogation n'aille même pas jusqu'à la table contenant les données. il est intéressant au niveau performances de le faire.NOM (pas son upper.. Créer un index basé sur une fonction et avoir la clause UPPER(nom)='MACHIN': CREATE INDEX INDVIDU_U_NOM on INDVIDUS(UPPER(NOM)). Mais cela n'est pas toujours possible. Autre souci majeur des index. Sur une base qui servira autant aux INSERT qu'aux SELECT la question est moins facile à trancher.. Pour qu'il soit utile. IV-E b . un index doit être tenu à jour tout comme le glossaire du livre quand on rajoute des chapitres. la question se pose moins.developpez.com/oracle/tuning/ . Il s'agira de trouver un compromis entre performances d'écritures et de lecture. il n'y a pas de réponse universelle. lui même). trigger . Dans le cas d'une base quasiment en lecture seule. Regardons ce qui se passe là: explain plan for (SELECT nom from indVidus where nom='MACHIN'). ce qui peut aussi nuire aux performances des INSERT et UPDATE . Plan: 1 INDEX RANGE SCAN INDEX OBLADI.12 Ce document est issu de http://www..

first_name from employees where last_name like 'T%').13 Ce document est issu de http://www.display()). http://jpg.com/oracle/tuning/ . c'est juste que comme toute l'information se trouve déja dans l'index. pourquoi irait il voir la table ? Un bon exemple est celui donné en II-F. il va bien.developpez.developpez. PLAN_TABLE_OUTPUT -------------------------------------------------------------------------------Plan hash value: 3085132068 -------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 5 | 75 | 1 (0)| 00:00:01 | |* 1 | INDEX RANGE SCAN| EMP_NAME_IX | 5 | 75 | 1 (0)| 00:00:01 | -------------------------------------------------------------------------------- . ExplicitÚ. modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.Initiation à l'optimisation de requêtes SQL sous ORACLE par Jean-Philippe GUILLOUX Oracle indique qu'il n'a rien fait d'autre qu'accéder à l'index ! Non. dans le schéma HR : SQL> explain plan for (select last_name.com et reste la propriété exclusive de son auteur. SQL> select plan_table_output from table(dbms_xplan. La copie.

com/oracle/tuning/ . CREATE TABLE MATABLE ( nom VARCHAR2(30). Ces structures sont souvent bien adaptées aux tables de paramètres qui changent peu. prenom VARCHAR2(20) ) ORGANISATION INDEX. Sur une table classique lorsqu'un index est parcouru il génère le plus souvent un accès à la table via les ROWID. dans une table organisée en index. l'information va là où elle doit aller.14 Ce document est issu de http://www. modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur. Il peut être alors nécéssaire de les reconstruire.Les tables organisées en index Les tables organisées en index sont des tables dont la structure est celle d'un index: les donnés y sont classées en arbre et les valeurs stockées directement dans la structure. La copie.com et reste la propriété exclusive de son auteur. ces valeurs sont rangées proprement dans des cases. Pour une information comme les précipitations météo organisées par villes et qui arrivent tous les jours celà peut être très efficace. les valeurs sont stockées directement dans la structure.developpez. Par exemple une liste des communes . On peut voir les choses de cette manière: dans une table normale les informations sont enregistrées à la suite les unes des autres quelques soient les valeurs..developpez.. http://jpg. Ces tables perdent de leurs performances lorsque trop de suppressions ont lieu.Initiation à l'optimisation de requêtes SQL sous ORACLE par Jean-Philippe GUILLOUX V . . Avec les tables organisées en Index.

com/oracle/tuning/ .. je disais que les index ralentissaient les insertions .. l'indexation des clefs étrangères peut amener un gain non négligeable ! Vous vous rappelez. et bien pas toujours. pensez y.. Imaginons un cas tout simple de clef étrangère: le champ CA de la table A référence le champ CB de la table B... La copie. Nous demandons ici à Oracle de vérifier que la valeur que l'on mettra dans CA existe bien dans CB . Une des extrémités (le champ reférencé) est souvent une clef primaire mais pas forcément.com et reste la propriété exclusive de son auteur. le référençant est rarement indexé.. NON ORACLE N'INDEXE PAS automatiquement les clefs étrangères (référentielles) de la base.developpez.developpez.. Et si le champ est indéxé il y a des chances que ça aille plus vite . L'autre extrémité. et bien comment croyez vous qu'il va la chercher cette valeur pour savoir si elle existe ? En accédant à la table .15 Ce document est issu de http://www. . modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur. une contrainte d'unicité suffit.. dans ce cas indexer sera judicieux.Clefs etrangères et index Halte aux idées reçues. Dans la grande majorité des cas. http://jpg. cela accelera les jointures et recherches qui pourraient se faire via ce champ.Initiation à l'optimisation de requêtes SQL sous ORACLE par Jean-Philippe GUILLOUX VI .

il préfèrera parfois faire un FULL TABLE SCAN. VII-D .Les stats Si vous avez fait de lourds changements dans une table n'oubliez pas de relancer l'analyse afin d'avoir des stats à jour. Quand Oracle estime de part les statistiques et les histogrammes qu'il devra ramener un gros pourcentage de lignes. on effectue une conversion de type implicite. Avec de mauvaises stats cela ne facilite pas la tâche à Oracle pour faire les bons choix . et donc une fonction et l'index bitmap ne sera pas utilisé . VII-C ..16 Ce document est issu de http://www.com/oracle/tuning/ ... un I/O pour accéder à la ligne .. En 10G Oracle arrive à éviter ce piège mais c'est une bonne pratique que de veiller à respecter les types car on peut vite arriver sur des cas complexes.Mais pourquoi Oracle n'utilise t'il pas mon index ? (le méchant) VII-A .com et reste la propriété exclusive de son auteur... VII-B . . autant prendre de suite les bonnes habitudes.. Il a souvent raison .. vous serez fixé . soit s'arranger pour ne pas avoir à appliquer de fonction (typiquement... quand on applique une fonction.developpez.. rien ne vous empêche de le forcer avec un hint. vous oublierez le sommaire pour allez chercher directement . car au final un accès par index a un coût: au moins un I/O pour l'index. Oracle fera un TO_CHAR sur le champs. http://jpg... Solution: Soit indexer le champ calculé avec la fonction. La copie... forcer les noms de famille en majuscule par exemple afin d'éviter un upper lors des recherches.La fonction qu'on ne voit pas . Et oui. l'index ne peut pas être utilisé. modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.....Initiation à l'optimisation de requêtes SQL sous ORACLE par Jean-Philippe GUILLOUX VII ... et peut même le conduire à en faire des mauvais . Si le champs MONTANT est un NUMBER..Ce n'est pas le meilleur chemin Oracle peut considérer au regard de ses statistiques que l'utilisation de l'index sera plus coûteuse que de parcourir complètement la table.La fonction . qu'il possède un INDEX BITMAP et qu'on exécute "select * from maTable where montant='1'".developpez. Solution: Surveillez les types dans les requêtes . Vous feriez pareil devant un livre où vous savez que vous devez lire 90% du contenu .). Si vous voulez le vérifier.

com et reste la propriété exclusive de son auteur. ..17 Ce document est issu de http://www. conserver de grosses tables en mémoire aurait des gros inconvénients au niveau occupation mémoire et performances . La copie.com/oracle/tuning/ . Ceci est particulièrement intéressant pour des petites tables de paramètres que vous accédez souvent. http://jpg..developpez. modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur. Attention toutefois à ne pas en abuser.developpez.Initiation à l'optimisation de requêtes SQL sous ORACLE par Jean-Philippe GUILLOUX VIII . lors de jointures par exemple.Tables en cache Vous pouvez demander à Oracle de conserver certaines tables en mémoire cache.

La copie. mais sachez qu'elles peuvent parfois être très intéressantes dans les problématiques de performances. Mais qui dit résultat stocké dit résultat de la requête à un moment t.com/oracle/tuning/ . et quand la table change la vue matérialisée sera tenue à jour ou non selon comment on l'a paramétrée.developpez.developpez. http://jpg. quand on crée une vue et qu'on l'interroge Oracle ne fait ni plus ni moins qu'une réécriture de requête .18 Ce document est issu de http://www. . Je ne m'étendrai pas ici sur les vues matérialisées: le web possède plein d'informations sur le sujet. Allez hop l'exemple: CREATE VIEW maVue AS (select * from maTable where monChamp=58). Le problème c'est qu'entretenir ces vues en temps réel est coûteux et pas souvent mis en oeuvre.Initiation à l'optimisation de requêtes SQL sous ORACLE par Jean-Philippe GUILLOUX IX ... Les vues matérialisées trouvent tout leur intêret dans des cas où l'on n'a pas besoin des données en temps reel. en particulier dans les datawarehouse. Les vues matérialisées sont des vues dont on stocke physiquement le résultat: le résultat de la requête est stocké comme pour une table... les données sont en réalité désormais figées et il peut être intéressant de stocker les résultats pour faire des sous interrogations plus rapidement. Chez Oracle. Dans ce cas.Vues matérialisées Une vue est en fait le fruit d'un requête. Quand on effectuera: select * from maVue where monChamp=45 Oracle lancera implicitement la requête: select * from (select * from maTable where monChamp=58) where monChamp=45 Oracle fait donc une simple réécriture de requête et exécute donc les requêtes imbriquées . modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.com et reste la propriété exclusive de son auteur. Par exemple l'analyse des chiffres économiques de la veille.

Je vais ici donner un exemple frappant que j'ai pu constater .TA...developpez.a. modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.a.a.b.c from TA. Select TA.TB where exists (select 1 from TB where TA.. http://jpg.. Une bien belle jointure que voilà .19 Ce document est issu de http://www. avec un nombre conséquent de lignes .. Mettre des index sur une base ne résoudra que partiellement les problèmes de performances. select TA.com/oracle/tuning/ . quand on rédige une requête il faut aussi penser à ce qu'on demande à oracle .developpez. Vous constaterez lors de tables avec de nombreux enregistrements.... mais au fait pourquoi fait-on une jointure ici ? alors qu'on ne ramène rien de TB ??? au final on ne fait que ramener de TA ce qui existe aussi dans TB selon la jointure .TA... imaginons deux tables TA et TB..TA.b. que celà est quand même bien plus rapide .TA.com et reste la propriété exclusive de son auteur. .a=TB.a).TB where TA.Initiation à l'optimisation de requêtes SQL sous ORACLE par Jean-Philippe GUILLOUX X .a=TB..c from TA.Les index ne font pas tout ..... La copie.

20 Ce document est issu de http://www. Pour celà il convient de réfléchir si on ne préfère pas stocker le nom en majuscules directement dans la base. http://jpg. Savoir faire les bons choix et refléchir aux coûts est primordial .. Il est fréquent que les utilisateurs désirent des recherches qui ne soient pas case-sensitive ou encore sans tenir compte des accents..com et reste la propriété exclusive de son auteur.En plus de l'optimisation de requête Une base performante se conçoit dès la phase de conception d'un projet. La copie.. Avant de pouvoir mettre le bon index sur une base il est nécéssaire de bien connaître le besoin.developpez.... Introduire de la redondance pour des raisons peut être payant mais doit s'étudier scrupuleusement ...developpez. modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur. cela évitera un upper() systématique . .com/oracle/tuning/ .Initiation à l'optimisation de requêtes SQL sous ORACLE par Jean-Philippe GUILLOUX XI . de bien savoir sur quels champs seront effectués les recherches .

La conception de la base est un élément clef.Conclusion Comme annoncé. une base efficace passe une architecture efficace. Enfin. http://jpg.. mais ce travail là relève du boulot du DBA . ce document ne fait que présenter en surface l'optimisation de requêtes .21 Ce document est issu de http://www.com/oracle/tuning/ . Enfin.developpez.. peut être intéressante à développer. La copie. modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur. RAM est primordial. bien dimensionner le serveur. .. Il existe beaucoup de paramètres influant sur les performances et il serait ici bien long de tous les citer . J'espère juste que ce document aura pu vous sensibiliser au fait qu'une requête même si on ne la juge pas coûteuse au premier abord.Initiation à l'optimisation de requêtes SQL sous ORACLE par Jean-Philippe GUILLOUX XII .developpez. au niveau processeur. ne serait-ce qu'en observant son plan d'exécution.com et reste la propriété exclusive de son auteur.... J'espère que cet article vous sera utile et aura permis une première approche du tuning de requêtes.

Enfin. orafrance. Merci à Olivier pour m'avoir autrefois initié à Oracle. je ne peux que vous encourager à regarder les multiples articles qui existent sur développez.developpez. http://jpg.22 Ce document est issu de http://www.com/oracle/tuning/ . fatsora.Initiation à l'optimisation de requêtes SQL sous ORACLE par Jean-Philippe GUILLOUX XIII .com et reste la propriété exclusive de son auteur.com/dbahelp/#L3 . conseils. suggestions et leurs encouragements. Scheu pour leurs relectures.Remerciements et liens Merci à Manu. à mnitu. modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur. La copie.developpez.developpez.com/guide/tuning/tkprof/ http://jaouad. corrections.com/conference-jonathan-lewis/ http://orafrance. de manière non exhaustive et dans aucun ordre précis: http://Oracle. Merci à Arnaud pour ses conseils et sa formation.developpez. Un grand merci aux membres de DVP. 3DArchi pour ses relectures attentives et ses corrections orthographiques. PlaineR.developpez. mon DBA préféré pour sa relecture.

Sign up to vote on this title
UsefulNot useful