Premier exemple
Eviter l’utilisation des index dans les clauses where
→ Consultation d’un plus grand nombre de blocs de donn´ees en utilisant l’index
plutˆot qu’en ex´ecutant un balayage complet de la table Am´elioration :
ajout d’une expression anodine `a la colonne d’index Par exemple :
ajout de+0`a une colonne num´erique
concat´enation d’une chaˆıne vide `a une colonne alphanum´erique positionnement du hint :
/∗+ FULL s i v o u s u t i l i s e z l ’ o p t i m i s e u r s t a t i s t i q u e . S e l e c t /∗+ FULL (EMP) PARALLEL (EMP, 2 ) ∗/ from EMP
Les codes SQL ` a ne pas ´ ecrire
Deuxi`eme exemple
Eviter de m´elanger ou de comparer des valeurs et des types de donn´ees de colonnes
→ l’optimiseur ignorera l’index Am´eliorations :
Si le type de colonne estNUMBER: ne pas ’utiliser de guillemets pour encadrer la valeur
Ne pas oublier d’encadrer une valeur avec ses guillemets lorsqu’elle est d´efinie comme de type alphanum´erique S e l e c t . . . from EMP where SALARY > ’ 1000 ’ ; −− M a u v a i s S e l e c t . . . from EMP where SALARY > 1000 ; −− Bon S e l e c t . . . from EMP where MANAGER = SMITH ; −− M a u v a i s
Les codes SQL ` a ne pas ´ ecrire
Troisi`eme exemple
Ne pas utiliser l’op´erateur IS NULL dans une colonne index´ee
→ l’optimiseur ignorera l’index
SELECT N emp , name , a d r from EMP name i s n u l l; NB: ce n’est plus vrai avec Oracle 11g
Les codes SQL ` a ne pas ´ ecrire
Quatri`eme exemple
En cas d’utilisation de curseurs ou du SQL dynamique : ne pas coder pas l’instruction avec des valeurs en dur
Empˆeche la r´eutilisation du code SQL dans le pool partag´e
→ Utiliser des variables li´ees :
S e l e c t . . . from EMP whereEMPNO = 2324 ;−− M a u v a i s
S e l e c t . . . from EMP whereEMPNO = : 1 ;−−Bon
EXECUTE IMMEDIATE ’ D e l e t e f r o m EMP w h e r e EMPNO = 2324 ’ ;−− M a u v a i s EXECUTE IMMEDIATE ’ D e l e t e f r o m EMP w h e r e EMPNO = : 1 ’ USING v a r i a b l e ;−−Bon
Les codes SQL ` a ne pas ´ ecrire
Am´elioration de l’utilisation des bind variables `a partir de Oracle 8i
→ Insertion du param`etreCURSOR_SHARING=force dans le fichier init.ora
NB :
Possibilit´e de d´efinir le param`etre au niveau session Mais possibilit´e d’augmentation des d´elais d’analyse Il peut ˆetre pr´ef´erable de r´e´ecrire le code
Les codes SQL ` a ne pas ´ ecrire
Pas d’instruction Insert, update ou delete dans une it´eration (une boucle PL/SQL) si les op´erations peuvent ˆetre r´ealis´ees en vrac (bulk)
Les codes SQL ` a ne pas ´ ecrire
Evitez l’utilisation des sous-requˆetes
→Impact n´egatif sur les performances de votre syst`eme en consommant beaucoup de ressources CPU
Solution : utilisation des vues en ligne (inline views), c’est-`a-dire des sous-requˆetes dans la clause from de l’instruction select, disponible depuis la version 7.3
Les codes SQL ` a ne pas ´ ecrire
Evitez les produit cartesien
Ne pas construire la clause from d’une instructionselect avec des tables qui n’apparaissent pas dans les conditions de jointure de la clause whereafin d’´eviter de r´ealiser un produit cart´esien
Regrouper la cr´eation des tables et l’insert
Si la table est cr´e´ee et aliment´ee, regrouper l’op´eration :
C r e a t e t a b l e X ( c o l 1 number, c o l 2 v a r c h a r 2( 3 0 ) . . . ) ; I n s e r t i n t o X s e l e c t c o l 1 , c o l 2 from Y . . . ; −− M a u v a i s
C r e a t e t a b l e X ( c o l 1 number, c o l 2 v a r c h a r 2( 3 0 ) . . . ) a s s e l e c t c o l 1 , c o l 2
from Y . . . ; −− Bon
Les codes SQL ` a ne pas ´ ecrire
Eviter l’utilisation deselect x from dual
Bien qu’elle semble innocente, elle peut consommer l’essentiel des performances de votre syst`eme
F o r i i n 1 . . 1 0 0 0 0 l o o p
S e l e c t SEQ . NEXTVAL i n t o m a v a r i a b l e from d u a l ; I n s e r t i n t o X v a l u e s( m a v a r i a b l e , . . . ) ; End l o o p ; −− M a u v a i s
F o r i i n 1 . . 1 0 0 0 0 l o o p
I n s e r t i n t o X v a l u e s(SEQ . NEXTVAL, . . . ) ; End l o o p ; −− Bon
Les codes SQL ` a ne pas ´ ecrire
Eviter l’utilisation deNOT IN
Privil`egier l’utilisation deNOT EXISTSplutˆot queNOT INdans les clauses where(voir l’utilisation d’une jointure externe)
avecnot in(lent)
avec jointure externe (plus rapide)
S e l e c t a . nom , a . prenom
From S a l a r i e a , F o n c t i o n b
Where a . nom = b . nom(+) and b . nom i s NULL
Les codes SQL ` a ne pas ´ ecrire
Utiliser l’op´erateurLIKE avec un caract`ere initial plutˆot que la fonction SUBSTR()
Dans le cas de requˆetes tr`es complexes contenant de nombreuses conditions OR
Envisager leur r´e´ecriture `a l’aide deUNION ALL Possibilit´e de d´ecoupage de la requˆete en modules bien dimensionn´es qui pourront ˆetre optimis´es plus facilement Rappel :
Op´erateurUNION: r´ecup´eration de l’ensemble des enregistrements retourn´es par les deux requˆetes Les doublons ne sont pas pris en compte Op´erateurUNION ALL: r´ecup´eration de tous les enregistrements y compris les doublons (contrairement `a l’op´erateurUNION)
Les codes SQL ` a ne pas ´ ecrire
Utiliser les index appropri´es, les plus s´electifs
La s´electivit´e des donn´ees est le ratio entre le nombre de cl´es uniques et le nombre de lignes
Plus elle approche 1.00, meilleur est l’index Cr´eer des index sur les colonnes de cl´es ´etrang`eres Utiliser des index composites
Ceux-ci doivent ˆetre class´es dans l’ordre d´ecroissant de s´electivit´e.
Les codes SQL ` a ne pas ´ ecrire
Utiliser des indexbitmaps lorsque la clause where
contient des colonnes `a faible cardinalit´e ou des op´erations logiques comme OR, AND ou NOT ex´ecut´ees sur ces colonnes renvoit un grand nombre de lignes de la table
(sauf pour les tables supportant un grand nombre d’op´erations DML simultan´ees, du fait de leur comportement
intrins`equement bloquant)
Les codes SQL ` a ne pas ´ ecrire
Utiliser des single-table hashs ou desindex clusters Ces m´ethodes fournissent des performances excellentes sur les tables relativement statiques mais interrog´ees sur une large plage de valeurs
Sachant qu’un cluster enregistre les donn´ees dans un bloc de mani`ere ordonn´ee, un balayage de plages utilisant un index sur ce cluster r´ealisera un plus petit nombre d’op´erations
d’entr´ees-sorties pour r´epondre `a la requˆete
Les codes SQL ` a ne pas ´ ecrire
Choisir de mani`ere active le type de jointure : nested loop, merge join ouhash join
Lors de la jointure de trois tables ou plus, essayez de structurer la requˆete pour r´ealiser l’´elimination la plus forte sur la premi`ere jointure
→ incorporer toutes les conditions sur une table dans la clause where.
Privil´egier le traitement en vrac (BULK COLLECT/ FORALL)
Les codes SQL ` a ne pas ´ ecrire
A partir d’Oracle 8i, remplacer DBMS_SQLpar la nouvelle fonctionnalit´eexecute immediate (fonctionne nettement mieux)
E x e c u t e i m m e d i a t e ’CREATE TABLE XX AS SELECT ∗ FROM YY ’ ;
En cas d’utilisation de l’optimiseur syntaxique (ce qui ne devrait plus durer)
Structurer les clauses fromde mani`ere `a ce que la table la plus petite soit la derni`ere d´efinie dans la liste des tables S’il est n´ecessaire d’acc´el´erer la cr´eation d’un index Augmenter la valeur du param`etreSORT_AREA_SIZE au niveau session