|
Publicité ' | |||||||||||||||||||||||
|
|
#1 | ||||
|
Invité de passage
![]() Inscription : mai 2011 Messages : 7 ![]() |
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 : Code :
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 :
|
||||
|
|
00
|
|
|
#2 | ||||
|
Expert Confirmé
![]() Inscription : mai 2002 Messages : 1 641 ![]() |
Bonjour,
Par rapport à votre jeux d'essai que voullez-vous comme résultat ? J'ai du mal à comprendre votre besoin pour l'instant. car présenté comme celà je ne vois pas l'approt du récursif, vu qu'un simple Code sql :
suffit ? Peut être que le jeux d'essai n'est pas pertinant ? si on reste sur l'idée du récursif, quel est votre condition d'entrée pour la 1ere requete ? Ceci me semble peu restrictif : Code sql :
|
||||
|
|
00
|
|
|
#3 |
|
Invité de passage
![]() Inscription : mai 2011 Messages : 7 ![]() |
Pour ne pas alourdir mon exemple j'ai mis uniquement les entités en relation. J'ai donc rajouté des couples qui n'ont aucune relation directe ou indirecte avec le reste de la liste. Ils ne doivent donc pas ressortir.
Pour mon point d'entrée, si je lance avec PERS1 ou PERS2 ou PERS 3 ... jusqu'à PERS11 je dois toujours obtenir en sortie les 11 personnes (PERS1 à PERS11) 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...). En revanche si j'amorce mon récursif avec PERS12, je dois n'avoir en réponse que PERS12, 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. Voilà j'espère avoir été plus clair. |
|
|
00
|
|
|
#4 | ||
|
Expert Confirmé
![]() Inscription : mai 2002 Messages : 1 641 ![]() |
Pourquoi ne pas faire un simple :
Code sql :
Ensuite si vous voullez vraiment faire du recursif, je n'y suis pas encore arrivé avec votre exemple...à suivre edit : je ne comprend toujours pas l'intérêt de faire du recursif dans votre cas, vu que votre besoin apparent est de sortir toutes les personnes qui ont une relation quelconque avec une autre entité. |
||
|
|
00
|
|
|
#5 | ||
|
Membre chevronné
![]() Administrateur de base de données Inscription : octobre 2006 Messages : 503 ![]() |
j'ai fait un truc, ca ne me plait pas bcp; je verrai si je peux améliorer lundi
Code :
|
||
|
|
00
|
|
|
#6 | |
|
Invité de passage
![]() Inscription : mai 2011 Messages : 7 ![]() |
Citation:
- D'une part sur des tables assez grosses (dasn mon cas environ 600.000 enreg) on retrouve le problèmes de doubons extrèmement pénalisant, car à chaque niveau on multiplie les résulats de manière exponentielle, a cause de l'interdiction du distinct dans le UNION ALL - On est obligé de fournir à DB2 un niveau d'arrêt (dans votre exemple 5), sinon il continue de manière infinie, et met la machine à genou assez rapidement. |
|
|
|
00
|
|
|
#7 | |
|
Invité de passage
![]() Inscription : mai 2011 Messages : 7 ![]() |
Citation:
Nota : je ne suis pas un fana du récursif, mais je ne vois pas d'autres façon d'y arriver à coup sur. |
|
|
|
00
|
|
|
#8 |
|
Membre chevronné
![]() Administrateur de base de données Inscription : octobre 2006 Messages : 503 ![]() |
Je me doutais qu'avec plusieurs milliers de lignes en entrée ca génèrerai plusieurs millions de lignes en sortie.
Ca ne me plaisait pas. il faut trouver le moyen "simple" d'arreter la requête et de ne pas générer des doublons. J'avais pensé à un "not exists", mais db2 refusait (je donnerai le sqlcode lundi) perso, à part faire avec un programme; je ne pense pas que le sql-récursif donne quelque chose de très efficace. Avec Oracle, il y a des trucs, mais spécifiques à oracle. |
|
|
00
|
|
|
#9 | |||
|
Membre Expert
![]() Patrick Inscription : mai 2008 Messages : 821 ![]() |
Salut,
Je prends cette discussion en cours. Citation:
Ta requête est bien, il te manquait juste un AND supplémentaire pour éviter des entrées supplémentaires. Ce qui donne : Code :
|
|||
|
|
10
|
|
|
#10 | ||
|
Membre Expert
![]() Patrick Inscription : mai 2008 Messages : 821 ![]() |
Celle-ci devrait être plus performante car elle limite au maximum les entrées indésirables donc la profondeur.
Code :
|
||
|
|
00
|
|
|
#11 |
|
Invité de passage
![]() Inscription : mai 2011 Messages : 7 ![]() |
|
|
|
00
|
Copyright © 2000-2012 - www.developpez.com