Complément pour un TME sur l'optimisation de requêtes
Septembre 2011
Schema des données
DiggExp(u,s,d) contient les votes des utlisateurs pour des articles
- u: l'utilisateur
- s: l'article voté par l'utilisateur
- d: la date du vote
Sim(u,f) : est le réseau d'amis
- u: l'utilisateur
- f: l'ami de l'utlisateur
Requête
Combien d'amis, ayant voté avant la date d0, possède l'utilisateur u0 ? Afficher le nombre d'amis de u0, qui ont voté au moins une fois avant la date d0. Les valeurs de u0 et d0 sont connues.
PLAN 1: Requête 'très' longue (dure 20 secondes)
select count(*) from Sim ami where ami.u = 23759 and ami.f in (select v.u from DiggExp v where v.d < 1238544008) ; --Ecoulé : 00 :00 :20.27
Explication:
Obtenir les amis de u avec l'index Sim.u : OK Puis, Pour chaque ami de u, oracle relis tous les nuplets de DiggExp dont la date <1238544008 en utilisant l'index sur DiggExp.d. On filtre à la volée si l'utilisateur est bien l'ami en question.
----------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ----------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 22 | 59 (0)| 00:00:01 | | 1 | SORT AGGREGATE | | 1 | 22 | | | | 2 | NESTED LOOPS SEMI | | 19 | 418 | 59 (0)| 00:00:01 | | 3 | TABLE ACCESS BY INDEX ROWID| SIM | 19 | 190 | 2 (0)| 00:00:01 | |* 4 | INDEX RANGE SCAN | IND_SIM_U | 19 | | 1 (0)| 00:00:01 | |* 5 | TABLE ACCESS BY INDEX ROWID| DIGGEXP | 7963K| 91M| 3 (0)| 00:00:01 | |* 6 | INDEX RANGE SCAN | IND_DIGGEXP_D | 1 | | 2 (0)| 00:00:01 | ----------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 4 - access("AMI"."U"=23759) 5 - filter("AMI"."F"="V"."U") 6 - access("V"."D"<1238544008)
PLAN 2 : Requête identique mais beaucoup plus rapide (dure 0,03 seconde)
select count(distinct ami.f) from Sim ami, DiggExp v where ami.u = 23759 and ami.f = v.u and v.d < 1238544008 ; Ecoulé : 00 :00 :00.03
Explications
Obtenir les amis de u avec l'index Sim.u : OK
Puis, pour chaque ami, acces aux nuplets de DiggExp correspondant à cet ami avec l'index DiggExp.u on filtre à la volée si la date est bonne
--------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | --------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 22 | 4700 (1)| 00:00:57 | | 1 | SORT AGGREGATE | | 1 | 22 | | | |* 2 | TABLE ACCESS BY INDEX ROWID | DIGGEXP | 253 | 3036 | 247 (0)| 00:00:03 | | 3 | NESTED LOOPS | | 4800 | 103K| 4700 (1)| 00:00:57 | | 4 | TABLE ACCESS BY INDEX ROWID| SIM | 19 | 190 | 2 (0)| 00:00:01 | |* 5 | INDEX RANGE SCAN | IND_SIM_U | 19 | | 1 (0)| 00:00:01 | |* 6 | INDEX RANGE SCAN | IND_DIGGEXP_USER | 376 | | 2 (0)| 00:00:01 | --------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - filter("V"."D"<1238544008) 5 - access("AMI"."U"=23759) 6 - access("AMI"."F"="V"."U")