• Aucun résultat trouvé

Bases de Données Avancées

N/A
N/A
Protected

Academic year: 2022

Partager "Bases de Données Avancées"

Copied!
88
0
0

Texte intégral

(1)

Bases de Donn´ ees Avanc´ ees

Thierry Hamon

Bureau H202 - Institut Galil´ee el. : 33 1.48.38.35.53 Bureau 150 – LIM&BIO – EA 3969 Universit´e Paris 13 - UFR L´eonard de Vinci 74, rue Marcel Cachin, F-93017 Bobigny cedex el. : 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)

Partie 2

Introduction

Pr´esentation des outils des m´ethodes

pour assurer le suivi de la base et garantir sa performance

(3)

Am´ elioration 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´eliorer l’optimisation de la base

(4)

Historique de l’optimiseur d’Oracle

Optimiseur Syntaxique

Avant la version 7.0 :

optimiseur syntaxique (rule-based optimizer) avant la version 7/0 :

Hypoth`ese de base :

`

a partir du moment o`u une instruction SQL validait une r`egle, et que le num´ero de la r`egle diminuait, le plan d’ex´ecution

´

etait r´eput´e meilleur.

Fonctionnement :

uniquement optimisation du code en utilisant un ensemble de r`egles internes fixes

et en les appliquant `a partir d’une analyse syntaxique du code

(5)

Historique de l’optimiseur d’Oracle

Optimiseur Syntaxique

Limites de l’optimiseur syntaxique : incapact´e `a d´eterminer la m´ethode la moins coˆuteuse

pas usage de type de fonction de coˆut ou de statistiques Mais, initialement con¸cu pour les BDD transactionnelles (les Datawarehouses n’existaient pas encore)

(6)

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´ecution du code SQL Mais maturit´e difficile `a atteindre : 7 ans !

A partir de Oracle 7.3 : Possibilit´e de g´en´erer et d’enregistrer des histogrammes de colonnes

Histogrammes de colonnes : Fonctionnalit´e capable de d´eterminer la distribution effective des donn´ees pour une colonne particuli`ere

(7)

Initialisation des Param´ etrage de l’Optimiseur

Configuration de l’instance Oracle `a l’aide du param`etre OPTIMIZER_MODE

Valeur d´efinie dans le fichier init.ora

Valeur par d´efaut : CHOOSE(valeur n´ecessaire pour l’optimisation statistique)

ValeurRULE : optimisation syntaxique (rule-based optimizer) Optimisation du code en utilisant un ensemble de r`egles internes fixes telles que :

Acc`es par l’interm´ediaire d’un index composite avec toutes les cl´es contenues dans la clausewhere

Acc`es par l’interm´ediaire d’un index sur une colonne, etc.

Autres valeurs possible (selon les versions d’oracle) :

(8)

Initialisation des Param´ etrage de l’Optimiseur

Modification du param`etre au niveau session `a l’aide de la commande suivante :

A l t e r s e s s i o n s e t o p t i m i z e r m o d e= f i r s t r o w s ;

(9)

Mode CHOOSE de l’Optimiseur

Obejectif de l’optimiseur :

tenter detout ex´ecuter en m´emoire 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´en´erer le plan d’ex´ecution des requˆetes

(10)

Mode CHOOSE de l’Optimiseur

En mode CHOOSE, la pr´esence de statistiques dans le dictionnaire d´etermine si l’optimiseur statistique est utilis´e Pas de mise `a jour r´eguli`ere des catalogues par Oracle Le DBA qui doit donc s’en charger

R´ecup´eration de la date de dernier calcul des statistiques : Requˆete dans la vueDBA_TAB_COLUMNS pour afficher l’information LAST_ANALYZED

s e l e c t owner , t a b l e n a m e , 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)

Collecte des statistiques

Calcul des statistiques d’objets :

Utilisation de la commandeANALYZEpour :

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´ees ou chain´ees d’une table d’un cluster, ...

(12)

Collecte des statistiques d’une table

Analyse statistique d’une partition (estimation sur la totalit´e 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)

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´e 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 c e n t ;

(14)

Suppression des statistiques d’une table et des index

ANALYZE TABLE emp DELETE STATISTICS

(15)

Quelle est la quantit´ e optimale des statistiques n´ ecessaire ?

Si estimation des statistiques des objets en se fondant sur un

´

echantillon (estimate) :

La taille de celui-ci doit ˆetre appropri´ee

El´´ement essentiel pour fournir `a l’optimiseur des statistiques dot´ees d’un bon intervalle de confiance

Un niveau de 20% est souvent utilis´e et semble appropri´e Si choix de calculer les stats (compute) :

Niveau de confiance : 100%

Et les statistiques doivent ˆetre parfaitement pr´ecises

ecessite des ressources et du temps pour r´ealiser ces calculs.

(16)

Quelle est la quantit´ e optimale des statistiques n´ ecessaire ?

S’il s’agit d’Oracle 8i ou sup´erieur, le packageDBMS_STATS pourra analyser les tables en parall`ele

Si ex´ecution d’une commandeanalyze estimate sur une taille d’´echantillon >49% :

le module calculera les statistiques sur l’ensemble de la table

(17)

Nouveaux packages pour la g´ en´ eration des statistiques

DBMS_UTILITY.ANALYZE_SCHEMA : analyse des sch´emas Oracle

DBMS_STATS : (nouveau package) statistique d’objets d’Oracle8i

(18)

textttDBMS UTILITY.ANALYZE SCHEMA

Analyse des sch´emas Oracle

Ex´ecution de la proc´edure 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)

DBMS STATS

Nouveau package de statistiques d’objets d’Oracle8i Ex´ecution de calculs avec diff´erentes options

Proc´edure Description

GATHER_INDEX_STATS Rassemblement de statistiques sur les index

GATHER_TABLE_STATS Rassemblement de statistiques sur les index, colonnes et tables

GATHER_SCHEMA_STATS Rassemblement de statistiques sur tous les objets d’un sch´ema

GATHER_DATABASE_STATS Rassemblement de statistiques sur tous les objets d’une base de donn´ees

(20)

DBMS STATS

Exemple d’utilisation d’option : Proc´edureGATHER_TABLE_STATS DBMS STATS . GATHER TABLE STATS

( ’DEV ’ , −−> Sch´ema

’ C o n t r a t ’ , −−> T a b l e

NULL, −−> P a r t i t i o n

3 0 , −−> % de l ’ ´e 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 ’ , −−> C o l o n n e s

4 , −−> D e g r´e de p a r a l l ´e l i s m e

’DEFAULT ’ , −−> T a b l e e t t o u t e s l e s p a r t i t i o n s TRUE) ; −−> C a s c a d e v e r s l e s i n d e x

(21)

DBMS STATS

Explications :

La table CONTRAT du user DEV est analys´ee avec un degr´e de parall´elisme de 4

Toutes les colonnes sont analys´ees ainsi que les index correspondants

L’analyse se fait avec une estimation de 30% au niveau ligne

(22)

DBMS STATS

Syntaxe

BEGIN

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) ;

END;

(23)

Restauration des statistiques avec DBMS STATS

Si les statistiques : semblent fausses

entraine l’Optimiseur `a g´en´erer des mauvauc plans d’ex´ecution 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)

Fr´ equence des statistiques

A quelle fr´equence les statistiques doivent ˆetre calcul´ees ?

→Cela d´epend du taux

du volume de changement des donn´ees dans la base

(25)

Suivi des Indicateurs

Indicateurs : Ratios

Alertes (corruption, messages d’erreurs etc.) et les traces Vues de d´epannage et r´eglage

Tuning des I/O des requˆetes couteuses

(26)

Ratios de la base

Buffer cache hit Rate

nombre de fois qu’un block utile `a la requˆete existe dans le buffer cache

→ il faut que ce pourcentage soit proche de 90%

s e l e c t r o u n d ((1−( p r .v a l u e/ ( bg .v a l u e+c g .v a l u e) ) )1 0 0 , 2 ) from v $ s y s s t a t p r , v $ s y s s t a t bg , v $ s y s s t a t c g

where p r . 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 emoire and c g . name= ’ c o n s i s t e n t g e t s ’ ; −− l e c t u r e s emoire

Objectif : avoir en m´emoire l’information dont on a besoin Am´elioration de ce ratio : augmenter ledb_block_buffers

(27)

Ratio de la base

Library cache get hit Rate

Proportion des requˆetes pour obtenir un verrou sur un objet Les requˆetes sont satisfaite en trouvant le descripteur de l’objet qui doit d´ej`a ˆetre en m´emoire

ce pourcentage doit ˆetre proche de 90%

s e l e c t r o u n d (sum( g e t h i t s ) /sum( g e t s )1 0 0 , 2 ) from v $ l i b r a r y c a c h e ;

Am´elioration des performances : Augmentation des valeurs SHARED_POOL_SIZE, etOPEN_CORSORS dansinit.ora

(28)

Ratio de la base

Dictionary Cache Hit Ratio

Mesure du taux de requˆetes pour obtenir des informations du dictionnaire de donn´ees, des tables et des vues contenant des informations sur

la base de donn´ees les structures les utilisateurs

(29)

Ratio de la base

Remarque :

Au d´emarrage, le cache du dictionnaire de donn´ees est vide Chaque requˆete SQL est absente du cache, et entraˆıne un efaut

Comme il y devrait y avoir de plus en plus de donn´ees lues dans le cache, le nombre de d´efaut dans le cache diminuera La base de donn´ees peut atteindre un ´etat stable (steady state) : les donn´ees du dictionnaires les plus fr´equemment utilis´ees sont dans le cache

(30)

Ratio de la base

Exemple d’utilisation

s e l e c t sum( g e t s−g e t m i s s e s )∗1 0 0 /sum( g e t s ) from v $ r o w c a c h e ;

Cache du dictionnaire : stock´e dans le Shared Pool(partie du SGA)

Am´elioration du ratio : augmentation de la taille dushare pool (SHARED_POOL_SIZE dans init.ora)

NB : A partir de la version 10g, la manipulation du catalogue est devenue plus intelligente

(31)

Ratio de la base

Sorts in Memory

Mesure de la proportion de donn´ees tri´ees qui sont en m´emoire plutˆot que sur le disque

Exemple :

s e l e c t r o u n d ( (mem .v a l u e/ (mem .v a l u e+d s k .v a l u e) )∗1 0 0 , 2 ) from v $ s y s s t a t mem, v $ s y s s t a t d s k

where mem . name= ’ s o r t s ( memory ) ’ and d s k . name= ’ s o r t s ( d i s k ) ’ ;

(32)

Ratio de la base

Remarques :

Le tri sur disque utilise lestablespaces temporaires

La taille maximal du tri en m´emoire est d´efini par la taille de la zone de tri (sort area size) – taille dans lequel de PGA est utilis´e

Chaque processus Oracle effectuant un tri r´eserve autant de emoire, mˆeme s’il n’en a pas besoin.

L’utilisation de cette m´emoire r´eduit celle disponible pour SGA Optimisation : augmenter le param`etreSORT_AREA_SIZE dans init.ora

(33)

Les alertes

Fichieralert_ORACLE_SID.log Exemple : alert_bdaINFO2.log Contenu d’un fichier d’alerte :

des informations utilis´ees par le DBA de la base pour une maintenance, un suivi, .. de la base Oracle

Des traces sont rajout´ees dans le fichier Log suite `a : un d´emarrage de la base,

un arrˆet de la base,

une cr´eation ou la mise `a jour d’un tablespace, une cr´eation, ou la mise `a jour d’un rollback segment, etc ...

(34)

Les alertes

Fichiers de traceOracle_Sid_numero.trc Ces fichiers contiennent des informations :

utile pour l’optimisation de la base : traces g´en´er´ees par les utilitairestkprof, statpack, utlbstat, etc.

ou permettent au DBA, de suivre et de corriger des erreurs, afin d’´eviter leplantage, ou un mauvais fonctionnement de la base Oracle

(35)

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 ( n o r m a l ) 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 . S y s t e m p a r a m e t e r s w i t h non−d e f a u l t v a l u e s:

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 = YYYYMMDD 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}/ d b s / o r a d a t a 1 / DWH ctl 1 . c t l ,

${HOME}/ dbdc / o r a c l e / d b s / 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 = 6 55 36

d b b l o c k s i z e = 1 63 84

ORA−1652: u n a b l e t o e x t e n d temp s e g m e n t by 64 i n t a b l e s p a c e S TBS INDX Wed Dec 3 1 2 : 2 5 : 4 9 2003

ORA−1652: u n a b l e t o e x t e n d temp s e g m e n t by 6400 i n t a b l e s p a c e S TBS DATA Wed Dec 3 1 2 : 2 8 : 5 1 2003

ALTER TABLESPACE S TBS DATAADDDATAFILE

(36)

Catalogue Oracle:Instance et base de donn´ ees

V$database : description de la base V$instance : description de l’instance V$parameter: param`etres de la base V$process~: nombre de process actifs

V$waitstat~: statistiques relatives aux attentes

V$system_event : attentes totales pour des ´ev`enements particuliers

(37)

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

CREATEDATABASE

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 i n s t a n c e n a m e 2 BCR D i n s t a n c e name s u p p o r t e d by t h e i n s t a n c e d b b l o c k s i z e 3 1 63 84 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

o p e n c u r s o r s 3 500 max# c u r s o r s p e r 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 6 0 0 0 0 0 0 s i z e o f i n−memory s o r t work a r e a r e t a i n e d between f e t c h c a 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 t o be r e a d e a c h IO m a x e n a b l e d r o l e s 3 148 max number o f r o l e s a u s e r c a n h a v e

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 s e g m e n t s i n SGA c a c h e

s g a m a x s i z e 6 1 1 7 8 5 6 9 3 9 2 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 2 6 8 4 3 5 4 5 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

(38)

Statistiques relatives aux attentes

S e l e c t ”CLASS” , ”COUNT” , ”TIME” from v $ w a i t s t a t ;

CLASS COUNT TIME

d a t a b l o c k 19 86 6 26 10 2

s o r t b l o c k 0 0

s a v e undo b l o c k 0 0

s e g m e n t 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

2 nd l e v e l bmb 0 0

3 r d l e v e l bmb 0 0

b i t m a p b l o c k 0 0

b i t m a p 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

u n u s e d 0 0

s y s t e m undo h e a d e r 0 0 s y s t e m 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)

attentes totales pour des ´ ev` enements particuliers

s e l e c t e v e n t , 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 1 9 2 9 7 3 7 293

e n q u e u e 10 93 7 103

c o n t r o l f i l e s e q u e n t i a l r e a d 5 9 6 4 2 7 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 1 8 7 0 2 2 1 3

b u f f e r b u s y w a i t s 2 71 44 1

l o g f i l e s e q u e n t i a l r e a d 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 4 4 3 2 7 2 0

LGWR w a i t f o r r e d o c o p y 12 49 0 0

db f i l e s e q u e n t i a l r e a d 1 7 3 4 7 6 0 db f i l e s c a t t e r e d r e a d 1 0 1 0 0 5 0 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 37 09 6 3

db f i l e p a r a l l e l r e a d 1 6

l i b r a r y c a c h e p i n 139 285

l i b r a r y c a c h e l o c k 149 11

l i b r a r y c a c h e l o a d l o c k 3 0

(40)

Catalogue d’Oracle : Disques

V$datafile : liste des fichiers des donn´ees

V$filestat : statistiques relatives aux I/O dans les fichiers de donn´ees

V$tempstat : informations sur les statistiques relatives aux op´erations des I/O pour les fichiers de donn´ees des TBS temporaires

V$segment_statistics : statistiques sur les I/O par segments

(41)

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)

Catalogue d’Oracle : M´ emoire

V$buffer_pool_statistics : statistiques sur buffer pool V$db_object_cache : objets de la base, dans le cache V$rowcache : ´echec et succ`es dans le dictionnaire V$sysstat : statistique sur l’instance d’Oracle V$librarycache : statistiques sur lelibrarycache

(43)

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)

Comment am´ eliorer le temps de r´ eponse des applications ?

Partitionnement Ex´ecution parall`ele

Tuning des entr´ees/sorties

D´etection des lignes chaˆın´ees ou migr´ees D´etection des Index inutilis´es

R´eorganisation des index Utilisation des Hints

Codes SQL `a ne pas utiliser

(45)

Cr´ eation d’une table partitionn´ ee sous Oracle

C r e a t e t a b l e f a c t u r e ( n u m f a c t number ( 5 ) ,

n u m a r t i c l e number( 5 ) , d a t e v e n t e d a t e

)

P a r t i t i o n by r a n g e ( d a t e v e n t e ) (

p a r t i t i o n p 2 0 0 3 1 2 v a l u e l e s s t h a n

( t o d a t e ( ’ 2004−01−01 ’ , ’YYYYMMDD ’ ) ) p a r t i t i o n p 2 0 0 4 0 6 v a l u e l e s s t h a n

( t o d a t e ( ’ 2004−07−01 ’ , ’YYYYMMDD ’ ) ) p a r t i t i o n p 2 0 0 4 1 2 v a l u e l e s s t h a n

( t o d a t e ( ’ 2005−01−01 ’ , ’YYYYMMDD ’ ) ) )

(46)

Ex´ ecution parall` ele de la cr´ eation d’index sous Oracle

C r e a t e i n d e x 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 n e x t 5M) p a r a l l e l e 3

N o l o g g i n g L o c a l;

(47)

Tuning des Entr´ ees/sorties

Desc V$filestat

file# : num´ero du fichier phyrds : lecture disque phywrts : ´ecriture disque

phyblkrd : nbre de block disque lus phblkwrt : nombre de block disque ´ecrits readtim : temps de lecture

writetim : temps d’´ecriture

(48)

Tuning des Entr´ ees/sorties

Pour les fichiers dont la colonne phyrds est importante : v´erifier si les tables sont acc´ed´ees en full scan

S e l e c t name ,v a l u e from V$SYSSTAT

Where name l i k e ’%t a b l e s c a n ( l o n g% ’

Si la valeur value est importante : v´erifier les applications ...

→ D´efinir les bons index

(49)

D´ etection des Lignes chaˆın´ ees ou migr´ ees

D´etection de l’´etat de chaˆınage d’une table Analyze table scott .EMP compute statistics

S e l e c t num rows , c h a i n c n t from d b a t a b l e s

where t a b l e n a m e = ’EMP ’ ;

→ Augmenter la valeur de pctfree de la table EMP

(50)

D´ etection des Lignes chaˆın´ ees ou migr´ ees

Etat de chaˆınage au niveau de la Base

D´etection de l’´etat 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 = ’ T a b l e F e t c h C o n t i n u e d Row ’ ;

(51)

D´ etection des Index inutilis´ es

Alter indexnom index monitoringusage;

S e l e c t i n d e x n a m e , u s e d From v $ i n d e x u s a g e

where i n d e x n a m e = ’NOM INDEX ’ ; Alter indexnom index nomonitoringusage;

(52)

Strat´ egies 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)

Strat´ egies d’indexation

Index de fonction :

C r e a t e i n d e x i d x c l t s n o m p r e n on c l i e n t (upper( nom ) , prenom ) ; C r e a t e i n d e x 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 ´e d u r e PL/SQL

Quand faut-il reconstruire les index ?

(54)

R´ eorganiser/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 ’ ) ;

→ Equivalent de´ ANALYZE INDEXVALIDATE STRUCTURE Desc Index_stats

lf_rows : Nombre de valeurs pr´esentes dans index lf_rows_len : Longueur de l’index (en octets) Del_lf_rows : Nombre de valeur supprim´ees

del_lf_rows_len : Longueur d’index supprim´ees (en octets)

(55)

R´ eorganiser/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 )∗1 0 0 m o y e n d e l from i n d e x s t a t s ;

→si moyen_del >20% alors reconstruire index a l t e r i n d e x s c o t t . i n d e x 1 r e b u i l d ;

(56)

Utilisation des hints

Hint :

indication plac´ee dans une requˆete pour orienter le plan d’ex´ecution

ressemble beaucoup `a un commentaire, `a l’exception du + apr`es 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`es important de placer le hint `a l’emplacement appropri´e du code SQL, id´ealement avant la r´ef´erence `a la premi`ere colonne du code SQL

Si le hint inclus est incorrect il sera tout simplement ignor´e

(57)

Utilisation des hints

Exemple/syntaxe g´en´erique :

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’indexde latable NO_INDEX(table, index): D´esactivation de l’indexde latable

ORDERED : Force l’ordre de jointure des tables, telles qu’elles apparaissent dans la clauseFrom

FIRST_ROWS : Force Oracle `a choisir le plan d’ex´ecution qui re- tourne lesnpremi`eres lignes de mani`ere la plus effi- cace

PARALLEL(table, n) : Sp´ecification desnserveurs concurrent pouvant ˆetre utilis´es pour une requˆete

(58)

Utilisation des hints

Outils d’aide :

PRECISE : suivi d’une base de production

TOAD : suivi du passage du prototypage `a la production OEM : Oracle Entreprise Manager

etc.

(59)

Utilisation des hints

Utilisation ORDERED: impose `a l’optimiseur d’utiliser les tables dans l’ordre d’apparition dans la requˆete SQL

S e l e c t /∗ + ORDERED ∗/ d . d e p a r t e m e n t n a m e , e . s u r n a m e from e m p l o y e e s e , d e p a r t e m e n t 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 . d e p a r t e m e n t n a m e = : 1 ;

(60)

Utilisation des hints

Utilisation INDEX : impose `a l’optimiseur d’utiliser les indexes sp´ecifi´es par le Hint INDEX

S e l e c t /∗ + INDEX ( e , e m p l o y e i d x ) ∗/ nom from e m p l o y e e s e

where e . d e p a r t e m e n t i d = : 1 and e . m a n a g e r i d = : 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 | c h o o s e ;

(61)

Diff´ erents types de hints

Optimisation :

FIRST_ROWS, ALL_ROWS: Force Oracle `a utiliser les premi`eers ou toutes les lignes

ORDERED: Acc`es aux tables dans l’ordrede de la clauseFROM Acc`es: FULL(tab),ROWID,PARALLEL

(62)

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 , n u m c o u r s , 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 . n u m e l e v e = e . n u m e l e v e and e . n u m e l e v e = 10 ;

SQL>SELECTLPAD( ’ ’ , 2∗(LEVEL−1 ) )| |o p e r a t i o n| | | | o p t i o n s | | | | o b j e c t n a m e ” P l a n d ’ e x ´e c u t i o n ”

2 FROM p l a n t a b l e

3 START WITH i d = 0AND s t a t e m e n t i d = ’ r e q u e t e 4 ’

4 CONNECT BY PRIOR i d = p a r e n t i d AND s t a t e m e n t i d = ’ r e q u e t e 4 ’ ; P l a n d ’ e x ´e 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 ´e l e c t i o n n ´e e ( s ) .

(63)

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 , n u m c o u r s , 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 . n u m e l e v e = e . n u m e l e v e and e . n u m e l e v e = 10 ; E x p l i c i t ´e .

SQL>SELECTLPAD( ’ ’ , 2∗(LEVEL−1 ) )| |o p e r a t i o n| | | |o p t i o n s | | | | o b j e c t n a m e ” P l a n d ’ e x ´e c u t i o n ”

2 FROM p l a n t a b l e

3 START WITH i d = 0AND s t a t e m e n t i d = ’ r e q u e t e 4 ’

4 CONNECT BY PRIOR i d = p a r e n t i d AND s t a t e m e n t i d = ’ r e q u e t e 4 ’ ; P l a n d ’ e x ´e 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

(64)

Impact des Hints

Exemple

Sans le Hint :

P l a n d ’ e x ´e 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 leHint : FULL(eleves)et FULL(resultat)

P l a n d ’ e x ´e 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)

Les codes SQL ` a ne pas ´ ecrire

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´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 .

(66)

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 S e l e c t . . . from EMP where MANAGER = ’ SMITH ’ ; −− Bon

(67)

Les codes SQL ` a ne pas ´ ecrire

Troisi`eme exemple : Ne pas utiliser l’op´erateur IS NULLdans 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; Quatri`eme exemple :

En cas d’utilisation de curseurs ou du SQL dynamique : ne pas coder pas ls 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

−−

(68)

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´ecrire le code

(69)

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)

D e c l a r e

C u r s o r . . . s e l e c t from X Begin

F o r 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 . c o l 1 , C u r s o r . c o l 2 1 . 5 , . . . ) ; Commit;

End l o o p ;

End ; −− M a u v a i s Begin

I n s e r t i n t o Z s e l e c t c o l 1 , c o l 2 1 . 5 from X where ;

(70)

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

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 ) ; −− M a u v a i s

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 g r o u p 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)

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´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

(72)

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

(73)

Les codes SQL ` a ne pas ´ ecrire

Eviter l’utilisation deNOT IN

Privil`egier l’utilisation deNOT EXISTSplutˆot queNOT IN dans les clauseswhere, voir l’utilisation d’une jointure externe

avecnot in(lent)

S e l e c t a . nom , a . prenom From S a l a r i e a Where a . nom n o t 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

(74)

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´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

(75)

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.

(76)

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)

(77)

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

(78)

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)

(79)

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

(80)

Vos requˆ etes SQL en mode trace

Les ´etapes du processus d’optimisation Activation d’une session en mode trace

(81)

Les ´ etapes du processus d’optimisation

1 erifier que le param`etreTIMED_STATISTICSest positionn´e `a TRUE au niveau instance

2 erifier que la valeur du param`etreMAX_DUMP_FILE_SIZEest suffisante Ce param`etre d´etermine la taille maximale du fichier de trace

3 eterminer l’emplacement point´e par le param`etreUSER_DUMP_DEST USER_DUMP_DEST: indication de l’emplacement o`u les fichiers de trace seront enregistr´es

4 Activer le param`etreSQL_TRACEpour la session concern´ee

5 Ex´ecuter l’application

6 Ex´ecutertkprofsur les fichiers de trace

7 Etudier le fichier de sortie detkprof

8 Ajuster les instructions SQL les plus coˆuteuses

(82)

Les ´ etapes du processus d’optimisation

Remarque : Ne pas positionner pas le param`etreSQL_TRACE `a TRUEdans le fichier init.ora:

Toutes les instructions SQL ex´ecut´ees seraient enregistr´ees, aboutissant `a un ralentissement sensible du syst`eme, ainsi qu’`a la saturation du syst`eme de fichiers

(83)

Activation d’une session en mode trace

Ex´ecution de la commande suivante :

a l t e r s e s s i o n s e t t i m e d s t a t i s t i c s = t r u e ; a l t e r s e s s i o n s e t s q l t r a c e = t r u e ;

. . .

−− e x e c u t i o n de v o s t r a i t e m e n t s . . . . . .

a l t e r s e s s i o n s e t t i m e d s t a t i s t i c s = f a l s e ; a l t e r s e s s i o n s e t s q l t r a c e = f a l s e ;

Remarques :

(`a partir de la version 7.2) il est possible de d´esactiver la trace

`

a partir d’une autre session

Ne pas d´esactiver la trace en annulant la session (kill)

(84)

TKPROF

Mettre la base ou la session en mode Trace : Base : mettreSQL_TRACE=TRUEdansinit.ora Session :

a l t e r s e s s i o n s e t SQL TRACE TRUE s e t a u t o t r a c e on

Utilisation deTKPROF: pour analyser le fichier trace Syntaxe :

TKPROF fichier_entree.trc fichier_sortie [Explain=username/password] [sys=no]

[insert=filename] [print=entier]

(85)

Exemple de TKPROF

SELECT NVL(TO_CHAR(CG,’YYYYMMDD’),’ ’)||C01||C02||C03||C04||C05||C06||C07 FROM

D21V2_ENGSEC WHERE CB = :0000

call count cpu elapsed disk query current rows

--- --- --- --- --- --- --- --- Parse 24562 2.64 2.66 0 0 0 0

Execute 24562 1.44 1.23 0 0 0 0 Fetch 24562 0.49 0.33 0 24562 0 0

--- --- --- --- --- --- --- --- total 73686 4.57 4.22 0 24562 0 0

Misses in library cache during parse: 0 Optimizer goal: RULE

Parsing user id: 34 Rows Row Source Operation

--- --- 0 TABLE ACCESS BY INDEX ROWID D21V2_ENGSEC

1 INDEX UNIQUE SCAN (object id 103435)

(86)

Interpr´ etation du r´ esultat de TKPROF

Call : La phase du traitement de l’instruction SQL (

les phases defineet bind sont incluses dans la phaseparse Count : Le nombre d’appels et d’ex´ecutions d’une phase CPU: Le temps CPU (en secondes) consomm´e pour l’ex´ecution d’une phase

Elapsed : Le temps CPU (en secondes) ´ecoul´e, cumul´e avec l’ensemble des temps utilis´es par le SE pour

ealiser les changements de contexte traiter les interruptions

epondre aux signaux ex´ecuter les entr´ees-sorties attendre les ressources

(87)

Interpr´ etation du r´ esultat de TKPROF

Disk : Le nombre de blocs Oracle lus sur le disque pour une phase donn´ee

Query : Le nombre de blocs Oracle lus en m´emoire en mode coh´erent (consistent mode)

Current : Le nombre de blocs Oracle lus en m´emoire en mode courant

Rows Le nombre de lignes trait´ees dans chaque phase, avec les valeurs pour les instructions select dans la phase fetch, et pour les op´eration insert,update dans la phaseexecute

(88)

Utilitaires et Outils d’optimisation

esum´e

TOAD OEM

TKPROF (outil capable de g´en´erer des traces) UTLBSTAT/UTLESTAT

STATPACK (UTL et STAT sont des outils ´equivalents qui permettent de recenser les requˆetes les plus consommatrices) Scripts du DBAs (le DBA doit d´evelopper ses scripts)

Références

Documents relatifs

Perdre ses photos de vacances : ¸ca n’a pas de

Imaginer et tester (avec phpPgAdmin ou dans l’interface en ligne de commande) des requˆ etes SQL pour r´ ecup´ erer les informations suivantes :2. a) L’ensemble des

Pour une distribution utilisant le syst` eme de paquetage dpkg (p. ex., Debian, Ubuntu, Linux Mint), vous pouvez installer l’ensemble de ces logiciels avec la commande :.. sudo

Cr´ eation d’une nouvelle relation RelE1-E2 Cl´ e de la relation : (cl´ e de E1, cl´ e de E2) Sch´ ema : Cl´ es et attribut de l’association TRAVAIL DANS (NSS, NUM,

Objectif : se restreindre ` a cet ensemble minimal pour concevoir le sch´ ema (logique) de la base de donn´ ees. D´ epart : Relation universelle et d´ ecomposition selon les

La boucle tant que est utilis ´ee lorsque le nombre d’it ´erations n’est pas connu `a l’avance: elle ex ´ecute le bloc d’instructions tant que la condition reste vraie.

◮ Retrouver les d ´epartements qui sont impliqu ´es dans le d ´eveloppement du jeu en r ´eseau peut se faire dans une sous-requ ˆete, dont le r ´esultat peut ˆetre utilis ´e dans

◮ “achet ´e des produits plusieurs fois” : il faut retrouver le d ´etail de chaque commande, pour v ´erifier si le m ˆeme produit apparaˆıt dans deux commandes diff