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

Persistance des données Java Discussion :

Optimisation de Recherche dans une Entité Mention


Sujet :

Persistance des données Java

  1. #1
    Membre confirmé Avatar de bruneltouopi
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2010
    Messages
    308
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Ile Maurice

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2010
    Messages : 308
    Points : 466
    Points
    466
    Par défaut Optimisation de Recherche dans une Entité Mention
    Bonjour j'ai une entité Mention avec cette structure
    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
    @Entity
    @Table(name = "mention")
    public class Mention implements DAOEntry {
     
        private static final long serialVersionUID = 1L;
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        @Basic(optional = false)
        @Column(name = "Id")
        private Integer id;
     
       private String grade
        private double noteMin;
        private double noteMax;
    //Getters et Setters
    }
    j'ai des enregistrements tels que:


    Grade NoteMin NoteMax
    D 1 5
    C 6 10
    B 11 15
    A 16 20
    Je gère les notes des étudiants.Je fais un select between dans la table Mention pour chaque note de l’étudiant pour avoir son grade.
    Donc pour une classe par exemple de 100 étudiants et pour 10 matières chaque étudiant ayant 2 notes, je fais nbreSelect=100*10*2=2000 requètes dans la table mention
    Je voudrais pouvoir charger les mentions par défauts dans une Collection(Map ou List) et faire un tri rapide Pour récupérer la mention d'un étudiant.
    Quelqu'un pourrait me proposer une solution adéquate pour optimiser mon processus?

    Merci
    Ce qui ne me tue pas me rend plus fort.

  2. #2
    Membre expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    2 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 938
    Points : 3 938
    Points
    3 938
    Par défaut
    Bonjour,
    le plus simple ce serait pas de faire un seul select pour charger en mémoire toute la table Mention?
    Et programmatiquement calculer ton grade?
    Donc au total tu auras 2 requêtes, une pour remonter tous les user et l'autre pour charger la table Mention.
    Vous avez peut être hâte de réussir et il n'y a rien de mal à cela...
    mais la patience est aussi une vertu; l'échec vous l'enseignera certainement..."

  3. #3
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Normalement, au sein d'une même transaction, ton entitymanager ne chargera pas deux fois le même row, car celui-ci sera gardé en cache. Autrement dit, si tu as 100 étudiants, 10 matières et 4 grades possibles pour chaque matière, tu chargera les 100 étudiant, les 10*100 associations etudiant-matière-grade, mais seulement 4 grades.

    Après tu peux regarder poru aller plus vite à charger toutes les matière d'un coup en désactivant le lazyloading sur les étudiant par exemple.

  4. #4
    Membre confirmé Avatar de bruneltouopi
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2010
    Messages
    308
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Ile Maurice

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2010
    Messages : 308
    Points : 466
    Points
    466
    Par défaut
    Citation Envoyé par DevServlet Voir le message
    Bonjour,
    le plus simple ce serait pas de faire un seul select pour charger en mémoire toute la table Mention?
    Et programmatiquement calculer ton grade?
    Donc au total tu auras 2 requêtes, une pour remonter tous les user et l'autre pour charger la table Mention.
    C'est c'est la première idée bref celle dont je voudrais utiliser.Mais comment charger en mémoire la table Mention?
    Programmatiquement je cherche aussi le meilleur Objet qui me permettra de récupérer les tris.

    Citation Envoyé par tchize_ Voir le message
    Normalement, au sein d'une même transaction, ton entitymanager ne chargera pas deux fois le même row, car celui-ci sera gardé en cache. Autrement dit, si tu as 100 étudiants, 10 matières et 4 grades possibles pour chaque matière, tu chargera les 100 étudiant, les 10*100 associations etudiant-matière-grade, mais seulement 4 grades.

    Après tu peux regarder poru aller plus vite à charger toutes les matière d'un coup en désactivant le lazyloading sur les étudiant par exemple.
    Ce ne sont pas les associations que je gères.J'ai une table NOtes qui contient les Notes des etudiants donc exemple :
    Etudiant1-Mat1-CC-11
    Etudiant1-Mat1-EX-18
    L'objectif est de Recuperer les Notes Puis de calculer le grade de l'étudiant.
    Pour la transaction je ne sais pas car lorsque je visualise ma console je constate que la requête se fait toujours.En plus la fonction de calcul est un select donc la plupart du temps je l'utilise juste dans les boucles Transactionnelles mais l'entityManager me fais toujours un Select à chaque opération
    Ce qui ne me tue pas me rend plus fort.

  5. #5
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Il faudrait que tu montre ton code.

    C'est sur que si tu fais


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    select * from Etudiant
     
    pour chaque étudiant parcourir les notes
     
    pour chaque note calculer le grade.
    Tu va faire N etudiant * M Matières = N*M select de 1 ligne de note, c'est pas cool

    Par contre, vu que tu dois tout parcourir, si tu fais

    select * from Etudiant
    select * from Matiere
    select * from Note


    tout sera en mémoire avec 3 selects et c'est réglé.


    L'alternative, c'est de faire directement la jointure dans ta requete de select pour avoir directement les Grades


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select g,n from Grade g, Note n where g.noteMin <= n.valeur and g.noteMax >= n.valeur
    Et tu obtiendra un liste de paires Grade / Note.

    Dans tous les cas, pour ton code actuel, attention que si tu fais le calul de la note, puis que fais un

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     from Grade g where g.noteMin <= :valeur and g.noteMax >= :valeur
    , forcément tu fera un select à chaque fois. Le cache joue uniquement quand tu demande un objet via son ID à l'entitymanager.

  6. #6
    Membre confirmé Avatar de bruneltouopi
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2010
    Messages
    308
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Ile Maurice

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2010
    Messages : 308
    Points : 466
    Points
    466
    Par défaut
    Bonjour;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    select g,n from Grade g, Note n where g.noteMin <= n.valeur and g.noteMax >= n.valeur
    J'aurai du mal à appliquer cette jointure directement dans le code car les méthodes de récuperations des notes sont déjà définies et utilisés Donc je devrais changer beaucoup l'existent cette méthode sera difficillement envisageable.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    from Grade g where g.noteMin <= :valeur and g.noteMax >= :valeur
    Exactement c'est cela que je fais.
    j'aimerais poster du code mais les traitements se font dans des scénaris
    Je manipule des Grades en fonction des scénarios.Je vais prendre 2 scénarios:
    Scenario 1
    a-Lister les Etudiants D'une classe =
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select e from Etudiant e where e.classe= :classeID
    b-Pour chaque étudiant il faut lister les matières choisies =
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select etUv from EtudiantUv where etUv.etudiant= :e
    c-Pour chaque matières choisies il faut trouver les notes=
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select n from Notes where n.etudiant= :e and n.matiere=:matiere
    d-Pour chaque note par exemple je peut donc soit trouver le grade ou appliquer des associations de notes pour enfin trouver la note finale Alors j'appellerai la fonction qui retrouve le grade en fonction de la Note.
    Scenario 2
    a-Pour une matière spécifique trouver les étudiants qui ont choisie la matière =
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select etUv from EtudiantUv where etUv.matiere= :e
    b-pour chaque étudiants qui ont choisi la matière recuperer les notes Voir scenario 1 c et d

    Bien je poste le code que j'utilises pour recuperer le grade en fonction d'une note.
    Moi j'aimerai juste pouvoir Charger au préalable cette table mention en mémoire et y faire des traitements.

    Voici un exemple de méthode Unitaire que j'appelle très souvent dans des Traitements
    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
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
        @Override
        public UnitedevaleurDto getFinalMarkForStudentForUv(Inscription ins, Unitedevaleur uv,double markAbsentCC,boolean applyResit) {
                 //recuperation des notes des sessions normales
                Collection<Notes> colNotesNormales = notesDao.getNotesExamenNormal(ins.getEtudiant(), ins.getEtablissements(), uv);
     
                //check s'il a moins une note de session normale
                //recuperation Note Rattrapage  
                UnitedevaleurDto uvDto = new UnitedevaleurDto(ins, uv, null);
                Integer ponderationExam = 0;
                Integer noteMaxExam = 0;
                double noteMaxExamPonderer = 0.0;
                double noteExamPonderer = 0.0;
                Integer ponderationCC = 0;
                //recuperation de la note sur laquelle on evalue
                Integer noteMaxCC = 0;
                //note max ponderer
                double noteMaxCcPonderer = 0.0;
                double noteCCPonderer = 0.0;
                //moyenne ou note a obtenir pour reussir
                double moyenne = 0.0;
                boolean haveNotesNormaleSession = false;
     
               if(applyResit==true){
                Notes noteRp = notesDao.getNotesResitByEtudiant(ins.getEtudiant(), uv);
                if (noteRp != null) {
                    Double noteResit = noteRp.getNoteRp();
                    if (noteResit == noteAbs || noteResit == null) {
                        noteResit = 0.0;
                    }
     
                    ponderationExam = noteRp.getExamen().getPonderation();
                    noteMaxExam = noteRp.getExamen().getNoteSure();
                    noteMaxExamPonderer = ponderationExam * noteMaxExam;
                    noteExamPonderer = noteResit * ponderationExam;
                    for (Notes notes1 : colNotesNormales) {
     
                        //si l examen de cette note doit etre pris avec le resit
                        if (notes1.getExamen().isProccesWithResit()) {
                            Double noteCC = notes1.getNote();
                            if (noteCC == noteAbs || noteCC == null) {
                                noteCC = 0.0;
                            }
                            ponderationCC = notes1.getExamen().getPonderation();
                            noteMaxCC = notes1.getExamen().getNoteSure();
                            noteMaxCcPonderer = noteMaxCC * ponderationCC;
                            noteCCPonderer = noteCC * ponderationCC;
                            haveNotesNormaleSession = true;
                        }
                    }
     
                    if (haveNotesNormaleSession) {
                        double totalMark = (noteCCPonderer + noteExamPonderer);
                        moyenne = (noteCCPonderer + noteExamPonderer) / (noteMaxCcPonderer + noteMaxExamPonderer);
                        uvDto.setFinalMark(totalMark);
                         Mention m=this.getMentionForNote(noteExamPonderer);
                    uvDto.setGrade(m.getLetterGrade());
                        uvDto.setPass(moyenne > 0.5);
                    } else {
                        uvDto.setFinalMark(markAbsentCC);
                         Mention m=this.getMentionForNote(noteExamPonderer);
                    uvDto.setGrade(m.getLetterGrade());
                        uvDto.setPass(false);
                    }
     
                }
               }else {
     
                    for (Notes notes1 : colNotesNormales) {
                        Double noteEx = notes1.getNote();
                        if (noteEx == noteAbs || noteEx == null) {
                            noteEx = 0.0;
                        }
     
                        if (notes1.getExamen().isProccesWithResit() && notes1.getExamen().getFinalExam()==false) {
                            haveNotesNormaleSession=true;
                         }
     
                        ponderationExam = notes1.getExamen().getPonderation();
                        noteMaxExam = notes1.getExamen().getNoteSure();
                        noteMaxExamPonderer += ponderationExam * noteMaxExam;
                        noteExamPonderer += noteEx * ponderationExam;
     
                    }
                     if(haveNotesNormaleSession){
                    moyenne = noteExamPonderer / noteMaxExamPonderer;
                    uvDto.setFinalMark(noteExamPonderer);
                    Mention m=this.getMentionForNote(noteExamPonderer);
                    uvDto.setGrade(m.getLetterGrade());
                    uvDto.setPass(moyenne > 0.5);
                     }else{
                    uvDto.setFinalMark(markAbsentCC);
                     Mention m=this.getMentionForNote(noteExamPonderer);
                    uvDto.setGrade(m.getLetterGrade());
                    uvDto.setPass(false);
     
                     }
               }
                return uvDto;
        }
    la Methode Mention m=this.getMentionForNote(noteExamPonderer); est la méthode unitaire qui va me chercher le grade pour une note

    Merci!
    Ce qui ne me tue pas me rend plus fort.

  7. #7
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Oui, ben là y a pas d'avance, tu peux essayer de tripatouiller hibernate tant que tu veux, si tu fais N query HQL, tu aura N query.

    Tu peux eventuellement jouer avec le query cache de hibernate, pour que les résultat les plus courant restent en cache. Genre t'as 10 cotes possible, on peut lui faire cacher le résultat de from Grade g where g.noteMin <= :valeur and g.noteMax >= :valeur pour chaque valeur. Pas top, mieux vaut revoir ta structure, mais ça peux aider.

  8. #8
    Membre confirmé Avatar de bruneltouopi
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2010
    Messages
    308
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Ile Maurice

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2010
    Messages : 308
    Points : 466
    Points
    466
    Par défaut
    Merci pour votre aide.Je vais tout d'abord regarder du coté de la cache Hibernate.
    Ce qui ne me tue pas me rend plus fort.

Discussions similaires

  1. optimisation recherche dans une table
    Par clod83 dans le forum Requêtes
    Réponses: 10
    Dernier message: 14/10/2011, 11h18
  2. optimiser le code d'une recherche dans une feuille excel
    Par h_adil dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 21/05/2008, 21h20
  3. recherche dans une table Access en ASP
    Par D-D dans le forum ASP
    Réponses: 3
    Dernier message: 09/06/2004, 10h12
  4. Problème de recherche dans une BD
    Par ledevelopeur dans le forum Bases de données
    Réponses: 5
    Dernier message: 28/04/2004, 09h49
  5. [BPW]Problème de recherche dans une boîte liste
    Par Alcatîz dans le forum Turbo Pascal
    Réponses: 14
    Dernier message: 05/07/2003, 15h10

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