Bonjour,
J'ai un petit soucis de performances en utilisant du SQL récursif.
Mon problème à la base est relativement simple, j'ai une personne qui peut être reliée à une entité, qui est elle-même reliée à d'autres personnes qui peuvent être liées à d'autres entités, qui elle mêmes, etc...
Je me suis donc dis que c'était typiquement du récursif et je suis parti dans cette voie.
Le problème est que à chaque fois que je descend d'un niveau, mon SQL reprEnd toutes les données trouvées précédemment, les remultiplie (jointures), et cela fin par donner des temps de réponses catastrophiques pour la bonne et simple raison que je ne peux pas rajouter de clause distinct après le UNION ALL (je suis sous Z.os). La bibliographie ne m'a pas apporté de réponse à ce sujet, alors voilà y a t il des astuces pour éviter cette multiplication à l'infini ?
Voici un exemple :
Pour mon point d'entrée, si je lance avec PERS1 ou PERS2 à PERS11 je dois toujours obtenir en sortie les 11 (PERS1 à PERS11) personnes et uniquement celles-la car elles ont toutes un lien entre elles (PERS1 est associé à ENT1, ENT1 lui même associé à PERS9, elle même associée à ENT7, etc...).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 CREATE TABLE COUPLE (NU_PERSONNE CHAR(8) NOT NULL NU_ENTITE CHAR(6) NOT NULL); INSERT INTO COUPLE VALUES ('PERS1', 'ENT1'); INSERT INTO COUPLE VALUES ('PERS2', 'ENT2'); INSERT INTO COUPLE VALUES ('PERS2', 'ENT4'); INSERT INTO COUPLE VALUES ('PERS2', 'ENT5'); INSERT INTO COUPLE VALUES ('PERS2', 'ENT6'); INSERT INTO COUPLE VALUES ('PERS2', 'ENT7'); INSERT INTO COUPLE VALUES ('PERS3', 'ENT4'); INSERT INTO COUPLE VALUES ('PERS3', 'ENT5'); INSERT INTO COUPLE VALUES ('PERS3', 'ENT6'); INSERT INTO COUPLE VALUES ('PERS3', 'ENT7'); INSERT INTO COUPLE VALUES ('PERS4', 'ENT3'); INSERT INTO COUPLE VALUES ('PERS4', 'ENT4'); INSERT INTO COUPLE VALUES ('PERS4', 'ENT5'); INSERT INTO COUPLE VALUES ('PERS4', 'ENT6'); INSERT INTO COUPLE VALUES ('PERS5', 'ENT3'); INSERT INTO COUPLE VALUES ('PERS6', 'ENT4'); INSERT INTO COUPLE VALUES ('PERS6', 'ENT5'); INSERT INTO COUPLE VALUES ('PERS6', 'ENT6'); INSERT INTO COUPLE VALUES ('PERS6', 'ENT7'); INSERT INTO COUPLE VALUES ('PERS7', 'ENT4'); INSERT INTO COUPLE VALUES ('PERS7', 'ENT5'); INSERT INTO COUPLE VALUES ('PERS7', 'ENT6'); INSERT INTO COUPLE VALUES ('PERS7', 'ENT7'); INSERT INTO COUPLE VALUES ('PERS8', 'ENT4'); INSERT INTO COUPLE VALUES ('PERS8', 'ENT5'); INSERT INTO COUPLE VALUES ('PERS8', 'ENT6'); INSERT INTO COUPLE VALUES ('PERS8', 'ENT7'); INSERT INTO COUPLE VALUES ('PERS9', 'ENT1'); INSERT INTO COUPLE VALUES ('PERS9', 'ENT7'); INSERT INTO COUPLE VALUES ('PERS10', 'ENT4'); INSERT INTO COUPLE VALUES ('PERS10', 'ENT5'); INSERT INTO COUPLE VALUES ('PERS10', 'ENT6'); INSERT INTO COUPLE VALUES ('PERS10', 'ENT7'); INSERT INTO COUPLE VALUES ('PERS11', 'ENT4'); INSERT INTO COUPLE VALUES ('PERS11', 'ENT5'); INSERT INTO COUPLE VALUES ('PERS11', 'ENT6'); INSERT INTO COUPLE VALUES ('PERS11', 'ENT7'); INSERT INTO COUPLE VALUES ('PERS12', 'ENT12'); INSERT INTO COUPLE VALUES ('PERS13', 'ENT13'); INSERT INTO COUPLE VALUES ('PERS14', 'ENT13');
En revanche si j'amorce mon récursif avec PERS12, je dois n'avoir en réponse que ENT12, car il n'y a aucune autre relation.
Et Enfin si j'amorce avec PERS12 ou PERS14, je dois obtenir en réponse PERS13 et PERS14 car liées entre elles par ENT13.
Sur cet exemple avec cette petite table les problèmes de doublons sont déjà pénalisants mais sur des tables conséquentes c'est inutile. D'autant plus que ces doublons m'empêchent de créée une condition de sortie autre que de compter les niveaux...
Ma requête de départ est la suivante :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 WITH RES_1 (NU_PERSONNE, NIVEAU) (SELECT DISTINCT B.NU_PERSONNE , 0 FROM COUPLE A JOIN COUPLE B ON A.NU_ENTITE = B.NU_ENTITE UNION ALL SELECT B.NU_PERSONNE , RES_1.NIVEAU + 1 FROM RES_1 JOIN COUPLE A ON A.NU_PERSONNE= RES.NU_PERSONNE JOIN COUPLE B ON A.NU_ENTITE = B.NU_ENTITE WHERE RES_1.NIVEAU < 10) SELECT DISCTINCT NU_PERSONNE FROM RES_1 WITH UR; )
Partager