1/88 Bases de Données Avancées Thierry Hamon Bureau H202 - Institut Galilée Tél. : 33 1.48.38.35.53 Bureau 150 LIM&BIO EA 3969 Université Paris 13 - UFR Léonard de Vinci 74, rue Marcel Cachin, F-93017 Bobigny cedex Tél. : 33 1.48.38.73.07, Fax. : 33 1.48.38.73.55 thierry.hamon@univ-paris13.fr http://www-limbio.smbh.univ-paris13.fr/membres/hamon/ INFO2 BDA
2/88 Partie 2 Introduction Présentation des outils des méthodes pour assurer le suivi de la base et garantir sa performance
3/88 Amélioration du Suivi et de la performance de la base 1 Choix de l optimiseur et collecte des statistiques 2 Suivi des indicateurs 3 Outils pour améliorer l optimisation de la base
4/88 Avant la version 7.0 : Historique de l optimiseur d Oracle Optimiseur Syntaxique optimiseur syntaxique (rule-based optimizer) avant la version 7/0 : Hypothèse de base : à partir du moment où une instruction SQL validait une règle, et que le numéro de la règle diminuait, le plan d exécution était réputé meilleur. Fonctionnement : uniquement optimisation du code en utilisant un ensemble de règles internes fixes et en les appliquant à partir d une analyse syntaxique du code
5/88 Historique de l optimiseur d Oracle Optimiseur Syntaxique Limites de l optimiseur syntaxique : incapacté à déterminer la méthode la moins coûteuse pas usage de type de fonction de coût ou de statistiques Mais, initialement conçu pour les BDD transactionnelles (les Datawarehouses n existaient pas encore)
6/88 Historique de l optimiseur d Oracle Optimiseur Statistique Apparition avec la version 7.0 d Oracle Objectifs : utilisation d un plus grand nombre d options lors de la construction des plans d exécution du code SQL Mais maturité difficile à atteindre : 7 ans! A partir de Oracle 7.3 : Possibilité de générer et d enregistrer des histogrammes de colonnes Histogrammes de colonnes : Fonctionnalité capable de déterminer la distribution effective des données pour une colonne particulière
7/88 Initialisation des Paramétrage de l Optimiseur Configuration de l instance Oracle à l aide du paramètre OPTIMIZER_MODE Valeur définie dans le fichier init.ora Valeur par défaut : CHOOSE (valeur nécessaire pour l optimisation statistique) Valeur RULE : optimisation syntaxique (rule-based optimizer) Optimisation du code en utilisant un ensemble de règles internes fixes telles que : Accès par l intermédiaire d un index composite avec toutes les clés contenues dans la clause where Accès par l intermédiaire d un index sur une colonne, etc. Autres valeurs possible (selon les versions d oracle) : FIRST_ROWS, ALL_ROWS
8/88 Initialisation des Paramétrage de l Optimiseur Modification du paramètre au niveau session à l aide de la commande suivante : Alter s e s s i o n set o p t i m i z e r m o d e=f i r s t r o w s ;
9/88 Mode CHOOSE de l Optimiseur Obejectif de l optimiseur : tenter de tout exécuter en mémoire centrale et donc diminuer au maximum les E/S (hit Ratio) Utilisation des calculs statistiques du catalogue Oracle (dba_tables, dba_indexes, les vues V$, etc...) pour générer le plan d exécution des requêtes
10/88 Mode CHOOSE de l Optimiseur En mode CHOOSE, la présence de statistiques dans le dictionnaire détermine si l optimiseur statistique est utilisé Pas de mise à jour régulière des catalogues par Oracle Le DBA qui doit donc s en charger Récupération de la date de dernier calcul des statistiques : Requête dans la vue DBA_TAB_COLUMNS pour afficher l information LAST_ANALYZED s e l e c t owner, table name, l a s t a n a l y z e d from d b a t a b c o l u m n s where l a s t a n a l y z e d > 01 JAN 00 ;
11/88 Collecte des statistiques Calcul des statistiques d objets : Utilisation de la commande ANALYZE pour : collecter ou supprimer des statistiques des tables (ou partition de table), d index (ou partition d index), cluster,... valider la structure des tables (ou partition de table), d index (ou partition d index), cluster,... identifier des lignes migrées ou chainées d une table d un cluster,...
12/88 Collecte des statistiques d une table Analyse statistique d une partition (estimation sur la totalité de la partition) ANALYZE TABLE emp PARTITION ( p1 ) COMPUTE STATISTICS ; Analyse statistique et validation de la structure d une table ANALYZE TABLE emp VALIDATE STRUCTURE; Analyse statistique d une partie d une table (exemple 33 %) ANALYZE TABLE emp ESTIMATE STATISTICS SAMPLE 33 p e r c e n t ; Analyse statistique d une table ainsi que de ses indexes ANALYZE TABLE emp COMPUTE STATISTICS FOR ALL INDEXED COLUMNS;
13/88 Collecte des statistiques d une Index Analyse statistique et validation de la structure d un index ANALYZE INDEX p a r t s i n d e x VALIDATE STRUCTURE; Analyse statistique ( sur la totalité de l index) ANALYZE INDEX i n d x 1 COMPUTE STATISTICS ; Analyse statistique d une partie d un index (exemple 44 %) ANALYZE INDEX p a r t s i n d e x ESTIMATE STATISTICS SAMPLE 44 p e r
14/88 Suppression des statistiques d une table et des index ANALYZE TABLE emp DELETE STATISTICS
15/88 Quelle est la quantité optimale des statistiques nécessaire? Si estimation des statistiques des objets en se fondant sur un échantillon (estimate) : La taille de celui-ci doit être appropriée Élément essentiel pour fournir à l optimiseur des statistiques dotées d un bon intervalle de confiance Un niveau de 20% est souvent utilisé et semble approprié Si choix de calculer les stats (compute) : Niveau de confiance : 100% Et les statistiques doivent être parfaitement précises Nécessite des ressources et du temps pour réaliser ces calculs.
16/88 Quelle est la quantité optimale des statistiques nécessaire? S il s agit d Oracle 8i ou supérieur, le package DBMS_STATS pourra analyser les tables en parallèle Si exécution d une commande analyze estimate sur une taille d échantillon > 49% : le module calculera les statistiques sur l ensemble de la table
17/88 Nouveaux packages pour la génération des statistiques DBMS_UTILITY.ANALYZE_SCHEMA : analyse des schémas Oracle DBMS_STATS : (nouveau package) statistique d objets d Oracle8i
18/88 textttdbms UTILITY.ANALYZE SCHEMA Analyse des schémas Oracle Exécution de la procédure analyze_schema du package DBMS_UTILITY Exemple : Execute d b m s u t i l i t y. a n a l y z e s c h e m a ( SCOTT, e s t i m a t e, e s t i m a t e p e r c e n t =>20) ;
19/88 DBMS STATS Nouveau package de statistiques d objets d Oracle8i Exécution de calculs avec différentes options Procédure GATHER_INDEX_STATS GATHER_TABLE_STATS Description Rassemblement de statistiques sur les index Rassemblement de statistiques sur les index, colonnes et tables GATHER_SCHEMA_STATS Rassemblement de statistiques sur tous les objets d un schéma GATHER_DATABASE_STATS Rassemblement de statistiques sur tous les objets d une base de données
20/88 DBMS STATS Exemple d utilisation d option : Procédure GATHER_TABLE_STATS DBMS STATS. GATHER TABLE STATS ( DEV, > Schéma C o n trat, > Table NULL, > P a r t i t i o n 30, > % de l é c h a n t i l l o n FALSE, > E c h a n t i l l o n de b l o c? FOR ALL COLUMNS, > Colonnes 4, > Degré de p a r a l l é l i s m e DEFAULT, > Table e t t o u t e s l e s p a r t i t i o n s TRUE) ; > Cascade v e r s l e s i n d e x
21/88 DBMS STATS Explications : La table CONTRAT du user DEV est analysée avec un degré de parallélisme de 4 Toutes les colonnes sont analysées ainsi que les index correspondants L analyse se fait avec une estimation de 30% au niveau ligne
22/88 DBMS STATS Syntaxe BEGIN END; DBMS STATS. g a t h e r t a b l e s t a t s ( DEV, CONTRAT, e s t i m a t e p e r c e n t => DBMS STATS. a u t o s a m p l e s i z e, CASCADE=>TRUE) ;
23/88 Restauration des statistiques avec DBMS STATS Si les statistiques : semblent fausses entraine l Optimiseur à générer des mauvauc plans d exécution Il faut restaurez les statistiques d Origines comme suit : BEGIN DBMS STATS. DELETE TABLE STATS ( s c o t t, emp ) ; DBMS STATS. IMPORT TABLE STATS ( s c o t t, emp, s t a t t a b => s a v e s t a t s ) ; END;
24/88 Fréquence des statistiques A quelle fréquence les statistiques doivent être calculées? Cela dépend du taux du volume de changement des données dans la base
25/88 Suivi des Indicateurs Indicateurs : Ratios Alertes (corruption, messages d erreurs etc.) et les traces Vues de dépannage et réglage Tuning des I/O des requêtes couteuses
26/88 Ratios de la base Buffer cache hit Rate nombre de fois qu un block utile à la requête existe dans le buffer cache il faut que ce pourcentage soit proche de 90% s e l e c t round ((1 ( pr. v a l u e /( bg. v a l u e+cg. v a l u e ) ) ) 1 0 0, 2 ) from v $ s y s s t a t pr, v $ s y s s t a t bg, v $ s y s s t a t cg where pr. name= p h y s i c a l r e a d s l e c t u r e s d i s q u e and bg. name= db b l o c k g e t s l e c t u r e s mémoire and cg. name= c o n s i s t e n t g e t s ; l e c t u r e s mémoire Objectif : avoir en mémoire l information dont on a besoin Amélioration de ce ratio : augmenter le db_block_buffers
27/88 Ratio de la base Library cache get hit Rate Proportion des requêtes pour obtenir un verrou sur un objet Les requêtes sont satisfaite en trouvant le descripteur de l objet qui doit déjà être en mémoire ce pourcentage doit être proche de 90% s e l e c t round (sum( g e t h i t s )/sum( g e t s ) 100,2) from v $ l i b r a r y c a c h e ; Amélioration des performances : Augmentation des valeurs SHARED_POOL_SIZE, et OPEN_CORSORS dans init.ora
28/88 Ratio de la base Dictionary Cache Hit Ratio Mesure du taux de requêtes pour obtenir des informations du dictionnaire de données, des tables et des vues contenant des informations sur la base de données les structures les utilisateurs
29/88 Ratio de la base Remarque : Au démarrage, le cache du dictionnaire de données est vide Chaque requête SQL est absente du cache, et entraîne un défaut Comme il y devrait y avoir de plus en plus de données lues dans le cache, le nombre de défaut dans le cache diminuera La base de données peut atteindre un état stable (steady state) : les données du dictionnaires les plus fréquemment utilisées sont dans le cache
30/88 Ratio de la base Exemple d utilisation s e l e c t sum( gets g e t m i s s e s ) 100/sum( g e t s ) from v$rowcache ; Cache du dictionnaire : stocké dans le Shared Pool (partie du SGA) Amélioration du ratio : augmentation de la taille du share pool (SHARED_POOL_SIZE dans init.ora) NB : A partir de la version 10g, la manipulation du catalogue est devenue plus intelligente
31/88 Ratio de la base Sorts in Memory Mesure de la proportion de données triées qui sont en mémoire plutôt que sur le disque Exemple : s e l e c t round ( (mem. value /(mem. value+dsk. value ) ) 1 0 0, 2 ) from v $ s y s s t a t mem, v $ s y s s t a t dsk where mem. name= s o r t s ( memory ) and dsk. name= s o r t s ( d i s k ) ;
32/88 Ratio de la base Remarques : Le tri sur disque utilise les tablespaces temporaires La taille maximal du tri en mémoire est défini par la taille de la zone de tri (sort area size) taille dans lequel de PGA est utilisé Chaque processus Oracle effectuant un tri réserve autant de mémoire, même s il n en a pas besoin. L utilisation de cette mémoire réduit celle disponible pour SGA Optimisation : augmenter le paramètre SORT_AREA_SIZE dans init.ora
33/88 Les alertes Fichier alert_oracle_sid.log Exemple : alert_bdainfo2.log Contenu d un fichier d alerte : des informations utilisées par le DBA de la base pour une maintenance, un suivi,.. de la base Oracle Des traces sont rajoutées dans le fichier Log suite à : un démarrage de la base, un arrêt de la base, une création ou la mise à jour d un tablespace, une création, ou la mise à jour d un rollback segment, etc...
34/88 Les alertes Fichiers de trace Oracle_Sid_numero.trc Ces fichiers contiennent des informations : utile pour l optimisation de la base : traces générées par les utilitaires tkprof, statpack, utlbstat, etc. ou permettent au DBA, de suivre et de corriger des erreurs, afin d éviter le plantage, ou un mauvais fonctionnement de la base Oracle
35/88 Exemple de fichier d alerte F r i Sep 12 1 1 : 4 6 : 0 1 2003 S t a r t i n g ORACLE i n s t a n c e ( normal ) LICENSE MAX SESSION = 0 LICENSE SESSIONS WARNING = 0 LICENSE MAX USERS = 0 S t a r t i n g up ORACLE RDBMS V e r s i o n : 8. 1. 7. 0. 0. System p a r a m e t e r s w i t h non d e f a u l t values : p r o c e s s e s = 320 s e s s i o n s = 357 t i m e d s t a t i s t i c s = TRUE n l s t e r r i t o r y = FRANCE n l s d a t e f o r m a t = YYYY MM DD n l s n u m e r i c c h a r a c t e r s =., c o n t r o l f i l e s = ${ORACLE HOME}/ dbs / o r a d a t a 1 / DWH ctl 1. c t l, ${HOME}/dbdc / o r a c l e / dbs / o r a d a t a 8 / DWH ctl 2. c t l d b b l o c k b u f f e r s = 65536 d b b l o c k s i z e = 16384 ORA 1652: unable to extend temp segment by 64 i n tablespace S TBS INDX Wed Dec 3 1 2 : 2 5 : 4 9 2003 ORA 1652: unable to extend temp segment by 6400 i n tablespace S TBS DATA Wed Dec 3 1 2 : 2 8 : 5 1 2003 ALTER TABLESPACE S TBS DATA ADD DATAFILE c :\ o r a c l e \ o r a n t \ o r a d a t \dbs\tbs DWH DATA 1. dbf SIZE 512M AUTOEXTEND OFF Wed Dec 3 1 2 : 2 8 : 5 9 2003
36/88 Catalogue Oracle:Instance et base de données V$database : description de la base V$instance : description de l instance V$parameter : paramètres de la base V$process~: nombre de process actifs V$waitstat~: statistiques relatives aux attentes V$system_event : attentes totales pour des évènements particuliers
37/88 Parametres de la base : v$parameter S e l e c t Name, Type, Value, d e s c r i p t i o n from v $ p a r a m e t e r NAME TYPE VALUE DESCRIPTION t i m e d s t a t i s t i c s 1 TRUE m a i n t a i n i n t e r n a l t i m i n g s t a t i s t i c s t r a c e e n a b l e d 1 TRUE e n a b l e KST t r a c i n g s q l t r a c e 1 FALSE e n a b l e SQL t r a c e db name 2 dwh d a t a b a s e name s p e c i f i e d i n CREATE DATABASE u t l f i l e d i r 2 u t l f i l e a c c e s s i b l e d i r e c t o r i e s l i s t instance name 2 BCR D instance name supported by the instance d b b l o c k s i z e 3 16384 S i z e o f d a t a b a s e b l o c k i n b y t e s open cursors 3 500 max # c u r s o r s per s e s s i o n s o r t a r e a r e t a i n e d s i z e 3 6000000 s i z e o f in memory s o r t work a r e a r e t a i n e d between f e t c h ca d b f i l e m u l t i b l o c k r e a d c o u n t 3 4 db b l o c k to be read each IO max enabled roles 3 148 max number of r o l e s a user can have e n a b l e d m a x r o l l b a c k s e g m e n t s 3 78 max. number o f r o l l b a c k segments in SGA cache s g a m a x s i z e 6 1178569392 max t o t a l SGA s i z e s h a r e d p o o l r e s e r v e d s i z e 6 26843545 s i z e i n b y t e s o f r e s e r v e d a r e a o f s h a r e d p o o l l a r g e p o o l s i z e 6 0 s i z e i n b y t e s o f t h e l a r g e a l l o c a t i o n p o o l j a v a p o o l s i z e 6 33554432 s i z e i n b y t e s o f t h e Java p o o l
38/88 Statistiques relatives aux attentes S e l e c t CLASS, COUNT, TIME from v$waitstat ; CLASS COUNT TIME data b l o c k 19866 26102 s o r t b l o c k 0 0 s a v e undo b l o c k 0 0 segment h e a d e r 5301 4161 s a v e undo h e a d e r 0 0 f r e e l i s t 0 0 e x t e n t map 0 0 1 s t l e v e l bmb 0 0 2nd l e v e l bmb 0 0 3 rd l e v e l bmb 0 0 bitmap b l o c k 0 0 bitmap i n d e x b l o c k 0 0 f i l e h e a d e r b l o c k 0 0 unused 0 0 system undo h e a d e r 0 0 system undo b l o c k 0 0 undo h e a d e r 1933 397 undo b l o c k 44 3
39/88 attentes totales pour des évènements particuliers s e l e c t event, t o t a l w a i t s, a v e r a g e w a i t from v $ s y s t e m e v e n t ; EVENT TOTAL WAIT AVERAGE WAIT l a t c h f r e e 3740 1 pmon t i m e r 1929737 293 enqueue 10937 103 c o n t r o l f i l e s e q u e n t i a l read 596427 0 c o n t r o l f i l e p a r a l l e l w r i t e 1870221 3 b u f f e r busy w a i t s 27144 1 l o g f i l e s e q u e n t i a l read 1571 0 l o g f i l e s i n g l e w r i t e 1562 1 l o g f i l e p a r a l l e l w r i t e 443272 0 LGWR wait f o r redo copy 12490 0 db f i l e s e q u e n t i a l read 173476 0 db f i l e s c a t t e r e d read 1010050 0 db f i l e s i n g l e w r i t e 104 1 db f i l e p a r a l l e l w r i t e 37096 3 db f i l e p a r a l l e l read 1 6 l i b r a r y cache p i n 139 285 l i b r a r y cache l o c k 149 11 l i b r a r y cache l o a d l o c k 3 0
40/88 Catalogue d Oracle : Disques V$datafile : liste des fichiers des données V$filestat : statistiques relatives aux I/O dans les fichiers de données V$tempstat : informations sur les statistiques relatives aux opérations des I/O pour les fichiers de données des TBS temporaires V$segment_statistics : statistiques sur les I/O par segments
41/88 Catalogue d Oracle : Contention V$lock : verrou externe V$latch : verrou interne d Oracle V$rollstat : statistiques sur les segments d annulation V$process : nombre de process actifs V$waitstat : statistiques sur les contention des blocks
42/88 Catalogue d Oracle : Mémoire V$buffer_pool_statistics : statistiques sur buffer pool V$db_object_cache : objets de la base, dans le cache V$rowcache : échec et succès dans le dictionnaire V$sysstat : statistique sur l instance d Oracle V$librarycache : statistiques sur le librarycache
43/88 Catalogue d Oracle : Session V$session : liste des sessions V$sesstat : statistiques des sessions V$session_event : informations sur les attentes d une session V$session_wait : attentes des sessions actives V$waitstat : statistiques relatives aux attentes V$open_cursor : liste des curseurs ouverts
44/88 Comment améliorer le temps de réponse des applications? Partitionnement Exécution parallèle Tuning des entrées/sorties Détection des lignes chaînées ou migrées Détection des Index inutilisés Réorganisation des index Utilisation des Hints Codes SQL à ne pas utiliser
45/88 Création d une table partitionnée sous Oracle Create t a b l e f a c t u r e ( num fact number ( 5 ), n u m a r t i c l e number ( 5 ), d a t e v e n t e date ) P a r t i t i o n by range ( d a t e v e n t e ) ( p a r t i t i o n p 200312 value l e s s than ( t o d a t e ( 2004 01 01, YYYY MM DD ) ) p a r t i t i o n p 200406 value l e s s than ( t o d a t e ( 2004 07 01, YYYY MM DD ) ) p a r t i t i o n p 200412 value l e s s than ( t o d a t e ( 2005 01 01, YYYY MM DD ) ) )
46/88 Exécution parallèle de la création d index sous Oracle Create index i d x t l c n t 1 on t l c n t ( n 0 c n t ) T a b l e s p a c e t b s i n d e x S t o r a g e ( i n i t i a l 10M next 5M) p a r a l l e l e 3 Nologging Local ;
47/88 Tuning des Entrées/sorties Desc V$filestat file# phyrds phywrts phyblkrd phblkwrt readtim writetim : numéro du fichier : lecture disque : écriture disque : nbre de block disque lus : nombre de block disque écrits : temps de lecture : temps d écriture
48/88 Tuning des Entrées/sorties Pour les fichiers dont la colonne phyrds est importante : vérifier si les tables sont accédées en full scan S e l e c t name, value from V$SYSSTAT Where name l i k e %t a b l e scan ( l o n g% Si la valeur value est importante : vérifier les applications... Définir les bons index
49/88 Détection des Lignes chaînées ou migrées Détection de l état de chaînage d une table Analyze table scott. EMP compute statistics Select num rows, c h a i n c n t from d b a t a b l e s where table name = EMP ; Augmenter la valeur de pctfree de la table EMP
50/88 Détection des Lignes chaînées ou migrées Etat de chaînage au niveau de la Base Détection de l état de chaînage au niveau de la base : s e l e c t from v $ s y s s t a t where s t a t i s t i c = Table Fetch Continued Row ;
51/88 Détection des Index inutilisés Alter index nom index monitoring usage; Select index name, used From v $ i n d e x u s a g e where index name = NOM INDEX ; Alter index nom index nomonitoring usage;
52/88 Stratégies d indexation Quand faut-il utiliser les index? Construction d index optimaux Quelques options d indexation : Non-unique index (index avec doublons) Unique index (index sans doublons) Bitmap index Hash partitionned index Composite partitioned index Reverse-key index Function-based index Descending index etc.
53/88 Stratégies d indexation Index de fonction : Create index i d x c l t s n o m p r e n on c l i e n t ( upper (nom ), prenom ) ; Create index i d x c l t s c a on c l i e n t ( c a l c u l c a ( i d c l i e n t ) ) ; c a l c u l c a e s t une p r o c é d u r e PL/SQL Quand faut-il reconstruire les index?
54/88 Réorganiser/Reconstruire un index? EXECUTE d b m s s t a t s. g a t h e r i n d e x s t a t s ( SCOTT, INDEX 1 ) ; Équivalent de ANALYZE INDEX VALIDATE STRUCTURE Desc Index_stats lf_rows lf_rows_len Del_lf_rows del_lf_rows_len : Nombre de valeurs présentes dans index : Longueur de l index (en octets) : Nombre de valeur supprimées : Longueur d index supprimées (en octets)
55/88 Réorganiser/Reconstruire un index? Quand reconstruire un index? S e l e c t name, ( d e l l f r o w s l e n, / l f r o w s l e n ) 100 moyen del from i n d e x s t a t s ; si moyen_del > 20% alors reconstruire index a l t e r index s c o t t. i n d e x 1 r e b u i l d ;
56/88 Hint : Utilisation des hints indication placée dans une requête pour orienter le plan d exécution ressemble beaucoup à un commentaire, à l exception du + après le /* Exemple : SELECT / + LE HINT / c o l o n n e ( s ) FROM t a b l e ( s ) WHERE... ; Remarques : Il est très important de placer le hint à l emplacement approprié du code SQL, idéalement avant la référence à la première colonne du code SQL Si le hint inclus est incorrect il sera tout simplement ignoré par l optimiseur, sans affichage de la moindre erreur!
57/88 Exemple/syntaxe générique : Utilisation des hints SELECT / + LE HINT / c o l o n n e ( s ) FROM t a b l e ( s ) WHERE... Instantiation de LE_HINT : FULL(table) : Parcours de toute la table (sans utiliser l index) INDEX(table, index) : Force l utilisation de l index de la table NO_INDEX(table, index) : Désactivation de l index de la table ORDERED : Force l ordre de jointure des tables, telles qu elles apparaissent dans la clause From FIRST_ROWS : Force Oracle à choisir le plan d exécution qui retourne les n premières lignes de manière la plus efficace PARALLEL(table, n) : Spécification des n serveurs concurrent pouvant être utilisés pour une requête etc. : (voir : http://download-west.oracle.com/docs/cd/b10501_01/server.920/a96533/hintsref.htm)
58/88 Utilisation des hints Outils d aide : PRECISE : suivi d une base de production TOAD : suivi du passage du prototypage à la production OEM : Oracle Entreprise Manager etc.
59/88 Utilisation des hints Utilisation ORDERED : impose à l optimiseur d utiliser les tables dans l ordre d apparition dans la requête SQL S e l e c t / + ORDERED / d. departement name, e. surname from employees e, departement d where d. d e p a r t e m e n t i d=e. d e p a r t e m e n t i d and d. departement name = : 1 ;
60/88 Utilisation des hints Utilisation INDEX : impose à l optimiseur d utiliser les indexes spécifiés par le Hint INDEX S e l e c t / + INDEX( e, e m p l o y e i d x ) / nom from employees e where e. d e p a r t e m e n t i d = : 1 and e. manager id = : 2 ; ALTER SESSION SET o p t i m i z e r g o a l= r u l e f i r s t r o w s a l l r o w s choose ;
61/88 Différents types de hints Optimisation : FIRST_ROWS, ALL_ROWS : Force Oracle à utiliser les premièers ou toutes les lignes ORDERED : Accès aux tables dans l ordrede de la clause FROM Accès: FULL(tab), ROWID, PARALLEL
62/88 Impact des Hints Exemple SQL> EXPLAIN PLAN 2 SET s t a t e m e n t i d = r e q u e t e 4 3 FOR s e l e c t nom, prenom, num cours, p o i n t s from e l e v e s e, r e s u l t a t s r 4 where r. num eleve = e. num eleve and e. num eleve = 10 ; SQL> SELECT LPAD(,2 (LEVEL 1)) o p e r a t i o n o p t i o n s object name Plan d exécution 2 FROM p l a n t a b l e 3 START WITH i d = 0 AND s t a t e m e n t i d = r e q u e t e 4 4 CONNECT BY PRIOR id = p a r e n t i d AND statement id = requete4 ; Plan d e x é c u t i o n SELECT STATEMENT NESTED LOOPS TABLE ACCESS BY INDEX ROWID ELEVES INDEX UNIQUE SCAN PK ELEVES TABLE ACCESS BY INDEX ROWID RESULTATS INDEX RANGE SCAN PK RESULTATS 6 l i g n e ( s ) s é l e c t i o n n é e ( s ).
63/88 Impact des Hints Exemple SQL> EXPLAIN PLAN 2 SET s t a t e m e n t i d = r e q u e t e 4 3 FOR s e l e c t / + FULL( e l e v e s ) FULL( r e s u l t a t s ) / nom, prenom, num cours, p o i n t s from e l e v e s e, r e s u l t a t s r 4 where r. num eleve = e. num eleve and e. num eleve = 10 ; E x p l i c i t é. SQL> SELECT LPAD(,2 (LEVEL 1)) o p e r a t i o n o p t i o n s object name Plan d exécution 2 FROM p l a n t a b l e 3 START WITH i d = 0 AND s t a t e m e n t i d = r e q u e t e 4 4 CONNECT BY PRIOR id = p a r e n t i d AND statement id = requete4 ; Plan d e x é c u t i o n SELECT STATEMENT HASH JOIN TABLE ACCESS BY INDEX ROWID ELEVES INDEX RANGE SCAN PK ELEVES TABLE ACCESS BY INDEX ROWID RESULTATS INDEX RANGE SCAN PK RESULTATS 6 l i g n e ( s ) s é l e c t i o n n é e ( s ).
64/88 Sans le Hint : Impact des Hints Exemple Plan d e x é c u t i o n SELECT STATEMENT NESTED LOOPS TABLE ACCESS BY INDEX ROWID ELEVES INDEX UNIQUE SCAN PK ELEVES TABLE ACCESS BY INDEX ROWID RESULTATS INDEX RANGE SCAN PK RESULTATS Avec le Hint : FULL(eleves) et FULL(resultat) Plan d e x é c u t i o n SELECT STATEMENT HASH JOIN TABLE ACCESS BY INDEX ROWID ELEVES INDEX RANGE SCAN PK ELEVES TABLE ACCESS BY INDEX ROWID RESULTATS INDEX RANGE SCAN PK RESULTATS
65/88 Les codes SQL à ne pas écrire Premier exemple Eviter l utilisation des index dans les clauses where Consultation par les instructions SQL d un plus grand nombre de blocs de données en utilisant l index plutôt qu en exécutant un balayage complet de la table Amélioration : ajout d une expression anodine à la colonne d index Par exemple : ajout de +0 à une colonne numérique concaténation d une chaîne vide à une colonne alphanumérique positionnement du hint : / + FULL s i vous 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 Where......
66/88 Les codes SQL à ne pas écrire Deuxième exemple Eviter de mélanger ou de comparer des valeurs et des types de données de colonnes l optimiseur ignorera l index Améliorations : Si le type de colonne est NUMBER : ne pas utiliser de guillemets pour encadrer la valeur Ne pas oublier d encadrer une valeur avec ses guillemets lorsqu elle est définie comme de type alphanumérique S e l e c t... from EMP where SALARY > 1000 ; Mauvais S e l e c t... from EMP where SALARY > 1000 ; Bon S e l e c t... from EMP where MANAGER = SMITH ; Mauvais S e l e c t... from EMP where MANAGER = SMITH ; Bon
67/88 Les codes SQL à ne pas écrire Troisième exemple : Ne pas utiliser l opérateur IS NULL dans une colonne indexée l optimiseur ignorera l index SELECT N emp, name, adr from EMP name i s n u l l ; Quatrième exemple : En cas d utilisation de curseurs ou du SQL dynamique : ne pas coder pas ls instruction avec des valeurs en dur Empêche la réutilisation du code SQL dans le pool partagé Utiliser des variables liées : S e l e c t... from EMP where EMPNO = 2324 ; Mauvais S e l e c t... from EMP where EMPNO = : 1 ; Bon EXECUTE IMMEDIATE Delete from EMP where EMPNO = 2324 ; Mauvais EXECUTE IMMEDIATE Delete from EMP where EMPNO = : 1 USING v a r i a b l e ; Bon
68/88 Les codes SQL à ne pas écrire Amélioration de l utilisation des bind variables à partir de Oracle 8i Insertion du paramètre CURSOR_SHARING=force dans le fichier init.ora NB : Possibilité de définir le paramètre au niveau session Mais possibilité d augmentation des délais d analyse Il peut être préférable de réécrire le code
69/88 Les codes SQL à ne pas écrire Pas d instruction Insert, update ou delete dans une itération (une boucle PL/SQL) si les opérations peuvent être réalisées en vrac (bulk) Declare C u r s o r... s e l e c t from X Begin For C u r s o r i n... Loop I n s e r t i n t o Z v a l u e s ( C u r s o r. col1, C u r s o r. c o l 2 1. 5,... ) ; Commit ; End l o o p ; End ; Mauvais Begin I n s e r t i n t o Z s e l e c t col1, c o l 2 1. 5 from X where ; Commit ; End ; Bon
70/88 Les codes SQL à ne pas écrire Evitez l utilisation des sous-requêtes Impact négatif sur les performances de votre système en consommant beaucoup de ressources CPU Solution : utilisation des vues en ligne (inline views), c est-à-dire des sous-requêtes dans la clause from de l instruction select, disponible depuis la version 7.3 S e l e c t e. from EMP e Where e. s a l a r y > ( s e l e c t avg ( s a l a r y ) from EMP i where i. d e p t i d = e. d e p t i d ) ; Mauvais S e l e c t e. from EMP e, ( s e l e c t i. d e p t i d DEP, avg ( i. s a l a r y ) SAL from EMP I group by d e p t i d ) EMP VUE where e. d e p t i d = EMP VUE. d e p t i d and e. s a l a r y > EMP VUE. SAL ; Bon
71/88 Les codes SQL à ne pas écrire Evitez les produit cartesien Ne pas construire la clause from d une instruction select avec des tables qui n apparaissent pas dans les conditions de jointure de la clause where afin d éviter de réaliser un produit cartésien Regrouper la création des tables et l insert Si la table est créée et alimentée, regrouper l opération : Create 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... ; Mauvais Create 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 )... ) as s e l e c t c o l 1, c o l 2 from Y... ; Bon
72/88 Les codes SQL à ne pas écrire Eviter l utilisation de select x from dual Bien qu elle semble innocente, elle peut consommer l essentiel des performances de votre système For 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 ; Mauvais For 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
73/88 Les codes SQL à ne pas écrire Eviter l utilisation de NOT IN Privilègier l utilisation de NOT EXISTS plutôt que NOT IN dans les clauses where, voir l utilisation d une jointure externe avec not in (lent) S e l e c t a. nom, a. prenom From S a l a r i e a Where a. nom not i n ( s e l e c t nom from F o n c t i o n where j o b = INFORMATICEN ) ; 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 And b. j o b = INFORMATICIEN ;