hotel (noms,nomh,categorie,adresse,tel,nb_chambres) station (noms,gare) activite (type_activite,noms)Pour chacune des requêtes suivantes, on demande:
SELECT adresse, tel, nb_chambres FROM hotel WHERE noms='pesey' AND categorie=3;(1) arbre syntaxique de la requête : Figure 9.1
SELECT noms, gare FROM station, activite WHERE type_activite = ``tennis'' AND station.noms=activite.nomsarbre syntaxique de la requête: Figure 9.1
cout(station Temp) = | { { { { { { { { |
|
./figures/q12_arbre_syntaxique.eps
Figure 9.1 : Arbres Syntaxique et Restructuration Algébrique pour les requêtes (1) et (2)
CREATE TABLE FILM ( CREATE TABLE VU ( TITRE VARCHAR2(32), SPECTATEUR VARCHAR2(32), REALISATEUR VARCHAR2(32), TITRE VARCHAR2(32) ACTEUR VARCHAR2(32) ); );Soit la requête SQL:
SELECT ACTEUR, REALISATEUR FROM FILM, VU WHERE FILM.TITRE=VU.TITREDans chacun des cas suivants, donner l'algorithme de jointure de ORACLE (par EXPLAIN, un arbre d'exécution commenté, une explication textuelle ou tout autre moyen de votre choix):
Plan d'exécution ------------------------------------------------------------------------ 0 SELECT STATEMENT 1 MERGE JOIN 2 SORT JOIN 3 TABLE ACCESS FULL VU 4 SORT JOIN 5 TABLE ACCESS FULL FILM
fi-optim2.ps
Figure 9.3 : Plan d'exécution
CREATE INDEX FILM_TITRE_idx on FILM (TITRE); Plan d'exécution ------------------------------------------------------------------------ 0 SELECT STATEMENT 1 NESTED LOOPS 2 TABLE ACCESS FULL VU 3 TABLE ACCESS BY ROWID FILM 4 INDEX RANGE SCAN FILM_TITRE_IDX
CREATE INDEX FILM_TITRE_idx on FILM (TITRE); CREATE INDEX VU_TITRE_idx on VU (TITRE); Plan d'exécution ----------------------------------------------------------------------- 0 SELECT STATEMENT 1 NESTED LOOPS 2 TABLE ACCESS FULL VU 3 TABLE ACCESS BY ROWID FILM 4 INDEX RANGE SCAN FILM_TITRE_IDX
SELECT e.enom, d.dnom FROM emp e, dept d WHERE e.dno = d.dno AND e.sal = 10000sur la relation EMP de schéma (EMPNO, SAL, MGR, DNO). Cette requête affiche le nom des employés dont le salaire (SAL) est égal à 10000, et celui de leur département. Indiquez le plan d'exécution dans chacune des hypothèses suivantes.
fi-optim3.ps
Figure 9.4 : Plan d'exécution
Plan d'execution -------------------------------------------------------------------------- 0 SELECT STATEMENT 1 NESTED LOOPS 2 TABLE ACCESS BY ROWID EMP 3 INDEX RANGE SCAN EMP_SAL 4 TABLE ACCESS BY ROWID DEPT 5 INDEX UNIQUE SCAN DEPT_DNOBoucles imbriquées (NESTED LOOP) : on choisit de parcourir un sous-ensemble de EMP en utilisant l'index, puis on accède a DEPT avec l'index sur DEPTNO.
fi-optim8.ps
Figure 9.5 : Plan d'exécution
Plan d'execution -------------------------------------------------------------------------- 0 SELECT STATEMENT 1 NESTED LOOPS 2 TABLE ACCESS FULL DEPT 3 TABLE ACCESS BY ROWID EMP 4 INDEX RANGE SCAN EMP_SALAlgorithme de SCAN-INDEX. Equivalent à une jointure par NESTED-LOOP brutal. On pourrait (i) changer l'ordre des tables sans modifier la complexité, et (ii) faire un tri-fusion.
fi-optim4.ps
Figure 9.6 : Plan d'exécution
Plan d'execution -------------------------------------------------------------------------- 0 SELECT STATEMENT 1 NESTED LOOPS 2 TABLE ACCESS FULL DEPT 3 TABLE ACCESS BY ROWID EMP 4 AND-EQUAL 5 INDEX RANGE SCAN EMP_DNO 6 INDEX RANGE SCAN EMP_SALComme l'index sur EMP(DNO) n'est pas unique, on a intérêt à limiter la liste des adresses de tuples en utilisant les deux index et en faisant l'intersection.
SELECT e.enom FROM emp e, dept d WHERE e.dno = d.dno AND d.ville = 'Paris'
Plan d'execution -------------------------------------------------------------------------- 0 SELECT STATEMENT 1 MERGE JOIN 2 SORT JOIN 3 TABLE ACCESS FULL DEPT 4 SORT JOIN 5 TABLE ACCESS FULL EMPAlgorithme de tri-fusion classique.
SELECT e.enom FROM emp e WHERE e.dno IN (SELECT d.dno FROM Dept d WHERE d.Ville = 'Paris')Voici le plan d'exécution donné par ORACLE :
0 SELECT STATEMENT 1 MERGE JOIN 2 SORT JOIN 3 TABLE ACCESS FULL EMP 4 SORT JOIN 5 VIEW 6 SORT UNIQUE 7 TABLE ACCESS FULL DEPTQu'en dites vous ? Création d'une table temporaire (VIEW) contenant les numéros des départements à Paris. On a éliminé les doublons (SORT UNIQUE). Ensuite on fait un tri-fusion. Donc exécution différente pour une requête équivalente.
SELECT * FROM EMP X WHERE X.SAL IN (SELECT SAL FROM EMP WHERE EMP.EMPNO=X.MGR)Cette requête cherche les employés dont le salaire (SAL) est égal à celui de leur patron (MGR). On donne le plan d'exécution avec Oracle (outil EXPLAIN) pour cette requête dans deux cas: (i) pas d'index, (ii) un index sur le salaire et un index sur le numéro d'employé. Expliquez dans les deux cas ce plan d'exécution (éventuellement en vous aidant d'une représentation arborescente de ce plan d'exécution).
Plan d'exécution ------------------------------------------------------------------------ 0 FILTER 1 TABLE ACCESS FULL EMP 2 TABLE ACCESS FULL EMPFigure 9.7.
Boucles imbriquées (FILTER) : On parcourt la table EMP (ligne 2); pour chaque employé, on regarde le salaire SAL et le numéro du patron MGR; on parcourt alors la table EMP (ligne 3) pour trouver l'employé dont le numéro est MGR et on compare le salaire à SAL. Donc c'est une boucle imbriquée brutale : on aurait pu faire un tri-fusion.fi-optim6.ps
Figure 9.7 : Plan d'exécution
Plan d'exécution ------------------------------------------------------------------------ 0 FILTER 1 TABLE ACCESS FULL EMP 2 AND-EQUAL 3 INDEX RANGE SCAN I-EMPNO 4 INDEX RANGE SCAN I-SALFigure 9.8.
Boucles imbriquées (FILTER) : on parcourt la table EMP (ligne 2). Pour chaque employé, le salaire SAL et le numéro EMPNO, valeur de l'attribut MGR servent de clé pour accéder à l'index (lignes 4 et 5). L'intersection des listes de row-id (ligne 3) obtenues par les étapes 4 et 5 donne si elle est non vide un row-id de patron ayant même salaire que l'employéfi-optim7.ps
Figure 9.8 : Plan d'exécution
SELECT * FROM EMP X WHERE X.SAL = (SELECT SAL FROM EMP WHERE EMP.EMPNO=X.MGR)on a le plan d'exécution suivant:
Plan d'exécution ------------------------------------------------------------------------ 0 FILTER 1 TABLE ACCESS FULL EMP 2 TABLE ACCESS ROWID EMP 3 INDEX RANGE SCAN I-EMPNOExpliquez-le. Dans ce cas, seul l'index sur les numéros d'employés est utilisé. Boucles imbriquées (FILTER); on parcourt la table EMP: pour chaque employé, l'attribut MGR donne le numéro d'employé de son patron. On accède à son patron par l'index sur les numéros d'employé (lignes 4 puis 3): on vérifie alors si son salaire est égal à celui de l'employé.
SELECT F.TITRE FROM SEANCE S, FILM F, ARTISTE A WHERE A.NOM = 'Hitchcock' AND F.ID-REALISATEUR = A.ID-REALISATEUR AND S.ID-FILM = F.ID-FILM AND S.HEURE_DEBUT > '20:00'
0 SELECT STATEMENT 1 MERGE JOIN 2 SORT JOIN 3 NESTED LOOPS 4 TABLE ACCESS FULL ARTISTE 5 TABLE ACCESS BY ROWID FILM 6 INDEX RANGE SCAN IDX-ARTISTE-ID 7 SORT JOIN 8 TABLE ACCESS FULL SEANCECommentez le plan donné par EXPLAIN. Pourrait-on améliorer les performances de cette requête? L'existence d'un tri-fusion indique qu'il manque un index. Ici on peut résoudre le pb en créant un index sur SEANCE(id-Film).
CREATE TABLE Artiste ( CREATE TABLE Film ( ID-artiste NUMBER(4), ID-film NUMBER(4), Nom VARCHAR2(32), Titre VARCHAR2(32), Adresse VARCHAR2(32) Année NUMBER(4), ); ID-réalisateur NUMBER(4) ); CREATE TABLE Joue ( ID-artiste NUMBER(4), ID-film NUMBER(4) );Questions:
SELECT nom, titre FROM artiste, film, joue WHERE artiste.ID-artiste = joue.ID-artiste AND film.ID-film = joue.ID-film
0 SELECT STATEMENT 1 MERGE JOIN 2 SORT JOIN 3 NESTED LOOPS 4 TABLE ACCESS FULL JOUE 5 TABLE ACCESS BY ROWID ARTISTE 6 INDEX UNIQUE SCAN ARTISTE_IDX 7 SORT JOIN 8 TABLE ACCESS FULL FILMComme il n'y a qu'un seul index utilisable, on fait un parcours séquentiel sur Joue pour utiliser l'index le plus tôt possible, puis on fait un tri fusion. On peut aussi faire le parcours séquentiel initial sur Film. Petit piège : l'index sur ID_réalisateur n'est pas utilisable pour la jointure.
0 SELECT STATEMENT 1 NESTED LOOPS 2 NESTED LOOPS 3 TABLE ACCESS FULL ARTISTE 4 TABLE ACCESS BY ROWID JOUE 5 INDEX RANGE SCAN JOUE_ARTISTE 6 TABLE ACCESS BY ROWID FILM 7 INDEX UNIQUE SCAN FILM_IDXComme il y a une seule table (ARTISTE) sans index propre à la jointure, on la choisit pour effectuer le parcours séquentiel initial.
0 SELECT STATEMENT 1 MERGE JOIN 2 SORT JOIN 3 NESTED LOOPS 4 TABLE ACCESS FULL JOUE 5 TABLE ACCESS BY ROWID FILM 6 INDEX UNIQUE SCAN FILM_IDX 7 SORT JOIN 8 TABLE ACCESS FULL ARTISTELes index existant ne peuvent servir qu'à une seule jointure : celle entre JOUE et FILM. Donc il ne reste que la solution de faire un TRI-FUSION pour la jointure avec ARTISTE. NB : on parcours JOUE puis on accède à FILM par l'index. On pourrait faire le contraire (parcourir FILM et accéder à JOUE). Quand il a des statistiques, le SGBD choisit la plus petite des tables pour le parcours séquentiel.