Bonjour,

j'essaie en ce moment de construire une requête en jpql qui compare deux dates pour ressortir tous les enregistrements entre ces dates du genre :

select * from maTable where dateDebut>=date and dateFin<= date;

cette requête est en fait une grosse requête construite à partir d'un écran d'une web app qui ajoute des paramètres en fonction de ce qui est rempli dans l'écran. malheureusement lorsque je compare les date elle devient beaucoup trop longue à exécuter (environ 5 min, alors qu'en faisant une égalité "classique" je tombe à une dizaine de secondes) tout ça sur une table assez peu volumineuse (quelques milliers de lignes).

je ne sais pas trop par quel bout prendre le problème étant donné que je ne suis pas professionnel dans tout ce qui est problèmes de sgbd...

pour info voici le code qui rempli ma requête :


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
100
private Query buildSearchPrestationQuery(boolean isCount,
    		DonneesDetailEntitesSante ddes, int prestationMode, java.util.Date desDateFacture1, java.util.Date desDateFacture2, java.util.Date desDateLot1, java.util.Date desDateLot2, String listNumMutuelles, String orderby) throws FonctionnelleException {
 
        Query q;
        int nbConditions = 0; //Compte le nombre de criteres renseignees
        boolean addAndToQuery =false; // indicateur s'il faut prefixe la clause par AND.
        StringBuffer requete = new StringBuffer();
        StringBuffer from = new StringBuffer();
        StringBuffer where = new StringBuffer();
 
        //Si on demande la construction d'une requete COUNT
        //LA REQUETE NE DOIT CONTENIR QUE LES CHAMPS UTILISES DANS LE TABLEAU DE SELECTION DES PRESTATIONS + DFI_ID et DFI_SENS et TYN_CODE_NORME
        if (isCount) requete.append("select count(1) ");
        //Sinon
        else {
        	requete.append("select NEW fr.metier.DonneesDetailEntitesSante(d.denId, d.desNumeroRo, d.desDateNaissance, d.desRangNaissance, d.desNom, d.desPrenom, d.desLienArchive, d.desNumFacture, d.desDateFacture ");
        	requete.append(", d.desNumLot, d.desDateLot, d.desCodeActe, d.desDateDebutSoins, d.desDateFinSoins, d.desNumeroFiness, d.desDateComptable ");
        	requete.append(", d.desNumeroEmeteur, d.desNumeroDestinataire, d.desGrdRegimeEmet, d.desGrdRegimeDest, d.desCaisseEmet, d.desOrganismeDest, d.desCentreEmet ");
        	requete.append(", d.desCentreDest, d.norReferenceNorme, d.norVersionNorme, d.mutNumeroOrigine, d.desRnm, d.tynCodeTypeNorme, d.norCodeNorme ");
        	requete.append(", d.donneesFichier.dfiId, d.donneesFichier.dfiSens, d.donneesFichier.dfiNomFichierSeul) ");
 
        }
        from.append(" from DonneesDetailEntitesSante d ");
        where.append(" where ");
 
 //Recherche par date de lot
        if (desDateLot1!= null ) {
            withDateLot1= true;
            if(addAndToQuery) where.append(" and ");
        	addAndToQuery=true;
            where.append("d.desDateLot >= :" + DonneesDetailEntitesSante.NQ_PARAM_DateLot1);
            nbConditions++;
        }
        if (desDateLot2 != null ) {
            withDateLot2= true;
            if(addAndToQuery) where.append(" and ");
        	addAndToQuery=true;
            where.append("d.desDateLot <= :" + DonneesDetailEntitesSante.NQ_PARAM_DateLot2);
            nbConditions++;
        }
 
        //Recherche par code acte
        if (StringUtils.isNotBlank(ddes.getDesCodeActe())) {
            withCodeActe= true;
            if(addAndToQuery) where.append(" and ");
        	addAndToQuery=true;
            if(ddes.getDesCodeActe().indexOf('%')<0){
            	where.append("d.desCodeActe = :" + DonneesDetailEntitesSante.NQ_PARAM_CodeActe);
            }else{
            	where.append("d.desCodeActe LIKE :" + DonneesDetailEntitesSante.NQ_PARAM_CodeActe);
            }
            nbConditions++;
        }
 
        //Recherche par Nature Operation
        if (StringUtils.isNotBlank(ddes.getDesNatureOperation())) {
            withNatureOperation= true;
            if(addAndToQuery) where.append(" and ");
        	addAndToQuery=true;
            if(ddes.getDesCodeActe().indexOf('%')<0){
            	where.append("d.desNatureOperation = :" + DonneesDetailEntitesSante.NQ_PARAM_NatureOperation);
            }else{
            	where.append("d.desNatureOperation LIKE :" + DonneesDetailEntitesSante.NQ_PARAM_NatureOperation);
            }
            nbConditions++;
        }
 
//Les deux dates suivantes sont celles qui posent problème...
 
        //Recherche par date debut de soins
        if (ddes.getDesDateDebutSoins()!= null) {
            withDateDebutSoins= true;
            if(addAndToQuery) where.append(" and ");
        	addAndToQuery=true;
        	//Si la date de fin de soin n'est pas renseignee ou si les dates de debuts et de fin sont identiques, on fait une simple egalite.
        	//Sinon on effectue une inegalité afin d'obtenir les enregistrement entre les deux dates.
        	if((ddes.getDesDateFinSoins()==null)||(ddes.getDesDateDebutSoins().equals(ddes.getDesDateFinSoins()))){
        		where.append("d.desDateDebutSoins = :" + DonneesDetailEntitesSante.NQ_PARAM_DateDebutSoins);
        	}
        	else{
        		where.append("d.desDateDebutSoins >= :" + DonneesDetailEntitesSante.NQ_PARAM_DateDebutSoins);
        	}
        		nbConditions++;
        }
 
        //Recherche par date fin de soins
        if (ddes.getDesDateFinSoins()!= null) {
            withDateFinSoins= true;
            if(addAndToQuery) where.append(" and ");
        	addAndToQuery=true;
        	//Si la date de debut de soin n'est pas renseignee ou si les dates de debuts et de fin sont identiques, on fait une simple egalite.
        	//Sinon on effectue une inegalité afin d'obtenir les enregistrement entre les deux dates.
        	if((ddes.getDesDateDebutSoins()==null)||(ddes.getDesDateFinSoins().equals(ddes.getDesDateDebutSoins()))){
        		where.append("d.desDateFinSoins = :" + DonneesDetailEntitesSante.NQ_PARAM_DateFinSoins);
        	}
        	else {
        		where.append("d.desDateFinSoins <= :" + DonneesDetailEntitesSante.NQ_PARAM_DateFinSoins);
        	}
            nbConditions++;
        }
J'ai volontairement raccourci la fonction car elle construit sur une trentaine de critères qui n'aurais pas d'intérêts à être afficher...

Comme vous pouvez le remarquer je construit de la même manière ma requête pour les critères dateLot1 & 2 et je ne rencontre aucun problème de performance avec ceux la... bref je pédale dans la semoule...

ps : je suis avec un sgbd oracle et j'utilise les ejb3 comme implémentation pour jpa et jsf 1.2 comme couche de présentation.

re ps : Je ne sais pas si je suis dans la bonne partie ici... merci de ne pas me trucider si c'est le cas