Complément pour un TME sur l'optimisation de requêtes


Septembre 2011

Schema des données

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

LesTravauxDirigés, Accueil