IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Autres Discussion :

Optimisation du mapping O/R [DAO]


Sujet :

Autres

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    124
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 124
    Points : 89
    Points
    89
    Par défaut Optimisation du mapping O/R
    Bonjour à tous,

    Je suis en train de développer un composant générique, permettant de générer automatiquement les requêtes d'accès aux données réalisées la couche métier (Mapping O/R).
    L'architecture est basée sur du 3-tier.
    Or je ne trouve aucun moyen simple de résoudre le problème du "N+1 Select".
    Je m'explique :
    Imaginons que nous avons un objet Etudiant et un objet Université. L'étudiant étudie dans une université.
    Sur une page, je veux afficher tous les étudiants, et le nom de l'université dans laquelle ils étudient.
    En SQL classique, pas de problème, me direz-vous :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT E.Nom, E.Prenom, U.Nom FROM Etudiant E, Universite U WHERE E.IDUniversite = U.IDUniversite
    Mais là on raisonne en termes de mapping Objet/Relationnel ! On procède donc ainsi :
    1) On charge tous les étudiants dans une collection
    2) Pour chaque (foreach) Etudiant E de la Collection, on récupère le nom de l'université associée
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    foreach(Etudiant E in EtudiantCollection)
    {
        /* Récupérer le nom */    
        E.SonUniversite.Nom 
    }
    Cette action, réalise implicitement (grâce à mon composant) la requête SQL de sélection suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT Nom FROM Universite WHERE IDUniversite IN (SELECT IDUniversite FROM Etudiant WHERE IDEtudiant = @Parametre)
    , le paramètre étant bien sûr l'ID de l'étudiant.

    C'est bien beau, ça marche parfaitement bien... si j'ai une vingtaine d'étudiants !!! Oui mais voilà, si j'ai 1000 étudiants dont je veux le nom de l'université, j'aurais 1000 requêtes SELECT générées, ce qui est totalement intolérable en termes de performances ! J'ai beau réfléchir, je ne vois pas de solution simple à ce problème. J'ai entendu parler du "Eager Fetching" mais j'ai pas vraiment compris...

    Voilà si quelqu'un à plus d'infos à me communiquer, ça serait sympa !

    @+

  2. #2
    ego
    ego est déconnecté
    Rédacteur

    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Juillet 2004
    Messages
    1 883
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Architecte de système d'information
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2004
    Messages : 1 883
    Points : 3 510
    Points
    3 510
    Billets dans le blog
    2
    Par défaut
    Eh bien, au lieu de réinventer un Nieme framework de mapping O/R, regardes Hibernate et tu verras que ta problématique est abordée !

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    124
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 124
    Points : 89
    Points
    89
    Par défaut
    Je sais, mais j'ai pas tout compris ! lol

  4. #4
    ego
    ego est déconnecté
    Rédacteur

    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Juillet 2004
    Messages
    1 883
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Architecte de système d'information
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2004
    Messages : 1 883
    Points : 3 510
    Points
    3 510
    Billets dans le blog
    2
    Par défaut
    Tu gagneras du temps à apprendre ce framework car un framework de mapping O/R est probablement une des choses les plus complexes à réaliser en informatique.........parole de vieux !

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    124
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 124
    Points : 89
    Points
    89
    Par défaut
    je sais lol mais j'ai déjà fini le mien, ou presque, à part ce fameux détail (et quel détail !)
    Bon, j'ai trouvé une méthode quand même depuis, je pense que ça doit rejoindre le mécanisme du EagerFetching... Simplement, lorsque je charge une collection, je donne la possibilité de spécifier optionnellement une ou plusieurs collection supplémentaires liées (ce qui réalisera implicitement une jointure dans la couche d'accès aux données)...
    Je l'ai pas encore mis en oeuvre, ça devrait pas être bcp plus compliqué que ce que j'ai déjà fait jusqu'à présent !


    P.S : La seule chose que j'aime pas trop dans cette solution, c'est que le développeur doit savoir à l'avance qu'il doit charger telle ou telle collection en parralèle. Si il n'y pense pas, ça ralentira le chargement (syndrôme N+1 SELECT), mais il risque de ne pas comprendre tout de suite pourquoi ....

  6. #6
    ego
    ego est déconnecté
    Rédacteur

    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Juillet 2004
    Messages
    1 883
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Architecte de système d'information
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2004
    Messages : 1 883
    Points : 3 510
    Points
    3 510
    Billets dans le blog
    2
    Par défaut
    Plusieurs points :

    Ta requête
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT Nom FROM Universite WHERE IDUniversite IN (SELECT IDUniversite FROM Etudiant WHERE IDEtudiant = @Parametre)
    n'est pas des plus efficace !! L'utilisation du "IN" n'est pas vraiment recommandé. Un jointure serait préférable.

    Je ne suis pas sûr que ton problème soit "N+1 SELECT". En fait, tu as tout simplement N Etudiant et pour chacun tu veux son université. Ton problème est donc de charger le plus efficacement les universités sachant que probablement, dans la cinématique de ton application, l'utilisateur demande les universités au fur et à mesure.
    Avec Hibernate, tu peux créer un objet "Composite", dans ton cas un objet de type EtudiantUniversité qui contient les attributs de Etudiant + le nom et l'ID (par exemple) de l'uiversité de rattachement. Ensuite, sans que cette classe ne soit référencé dans le fichier de mapping, tu peux faire des requêtes HQL comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT new EtudiantUniversité(e.att1,e.att2,...,u.id, u.nom) FROM Etudiant e, Universite u WHERE....
    Bien sûr, il faut, au niveau du code client, savoir que l'on doit utiliser cet objet particulier.

    Autre point, l'objet n'est pas souvent pratique pour les opération ensembliste; d'où les "entorses" nécessaires

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    124
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 124
    Points : 89
    Points
    89
    Par défaut
    Oui, la requête elle est pas très optimisée. Mais pour l'instant c'était plus facile à générer.
    Je ne connais pas trop le DP Composite, je vais voir ça d'un peu plus près.. Bon par contre le HQL ça me plait moyen, on a l'impression de tourner un peu en rond et de revenir au point de départ (SQL).. c pour ça que mon principe de chargement simultané me plaisait pas mal... Mais bon tu as sans doute raison, il faut savoir faire "quelques entorses"..
    Merci en tout cas

  8. #8
    ego
    ego est déconnecté
    Rédacteur

    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Juillet 2004
    Messages
    1 883
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Architecte de système d'information
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2004
    Messages : 1 883
    Points : 3 510
    Points
    3 510
    Billets dans le blog
    2
    Par défaut
    Pour info le HQL ressemble à SQL mais on y mentionne des classes. C'est Hibernate qui se charge de la création du SQL

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [AC-97] Optimisation d'un trajet et de son temps à partir de l'API Google Map
    Par tom-kun dans le forum VBA Access
    Réponses: 3
    Dernier message: 27/06/2019, 11h08
  2. [Projet en cours] Quake map devtool d'optimisation pour moteurs scriptés
    Par idmapria dans le forum Projets
    Réponses: 0
    Dernier message: 14/04/2012, 15h28
  3. Optimisation Affichage Map Iso avec Images
    Par Jerede dans le forum VB.NET
    Réponses: 21
    Dernier message: 31/05/2010, 08h11
  4. Editeur de MAP en delphi pour jeux directX
    Par PetitScorpion dans le forum DirectX
    Réponses: 5
    Dernier message: 09/07/2002, 18h47
  5. [langage] Optimiser la lecture d'un fichier
    Par And_the_problem_is dans le forum Langage
    Réponses: 2
    Dernier message: 11/06/2002, 10h24

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo