Précédent   Forum du club des développeurs et IT Pro > Bases de données > Oracle > SQL
SQL Forum d'entraide sur le SQL pour Oracle
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 03/12/2012, 11h05   #1
erox44
Membre actif
 
Homme
Développeur Web
Inscription : avril 2007
Messages : 360
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 24
Localisation : France, Loire Atlantique (Pays de la Loire)

Informations professionnelles :
Activité : Développeur Web

Informations forums :
Inscription : avril 2007
Messages : 360
Points : 166
Points : 166
Par défaut [OPTI] Requête gourmande

Salut à tous,
dans mon application j2ee je fais l'appel à cette requete :

Code :
1
2
3
4
5
6
7
SELECT sum(valeur)
FROM pt_chron_res_u pt, chron_res_u ch
WHERE pt.id_chron_res_u = ch.id_chron_res_u
AND ch.id_etude=15032
AND ch.type IN ('RPRIM','RSEC','PRODUCTION')
AND pt.date_res_u >= ( SELECT date_debut FROM marge_periode WHERE marge_periode.id_calcul=101 AND marge_periode.id_etude=15032 AND marge_periode.numero_periode=1 )
AND pt.date_res_u < ( SELECT date_fin FROM marge_periode WHERE marge_periode.id_calcul=101 AND marge_periode.id_etude=15032 AND marge_periode.numero_periode=1 )
le plan d'execution est en PJ.

la structure des tables est la suivante :

|----------------|
| CHRON_RES_U |
|----------------|
| id_chron_res_u |
| type |
| id_etude |
|----------------|

|-------------------|
| PT_CHRON_RES_U |
|-------------------|
| id_chron_res_u |
| date_res_u |
| valeur |
|-------------------|

|----------------|
| MARGE_PERIODE |
|----------------|
| id_calcul |
| numero_periode |
| id_etude |
| date_debut |
| date_fin |
|----------------|

Voici les index présent sur la table PT_CHRON_RES_U :
Code :
CREATE INDEX A_PT_CHRON_RES_U_FK ON PT_CHRON_RES_U
Code :
CREATE UNIQUE INDEX PK_PT_CHRON_RES_U ON PT_CHRON_RES_U

Le problème là, c'est que la dite requete prend entre 30s et 45s pour s'executer et que je dois le faire 15 fois (pour un numéro de période allant de 1 à 15), du coup je cherche à l'optimiser au max mais là, mais à part ajouter un index sur la table PT_CHRON_RES_U, sur l'id, jvois pas, car c'est cette table qui apparement pose soucis.
__________________
L'intelligence c'est comme la confiture, moins tu en as , plus tu l'étales...
erox44 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/12/2012, 11h41   #2
skuatamad
Expert Confirmé
 
Inscription : août 2008
Messages : 1 690
Détails du profil
Informations forums :
Inscription : août 2008
Messages : 1 690
Points : 2 812
Points : 2 812
Le plan n'est pas lisible, il est préférable de le récurérer via sqlplus et de le poster dans des balises codes (bouton #)
Il manque les colonnes sur lesquels portent les index.

La requête ne semble pas optimisée, que donne la requête réécrite comme çà ? (déjà en terme de résultat)
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
WITH t AS (
SELECT ch.id_chron_res_u, m.date_debut, m.date_fin
  FROM chron_res_u ch
  JOIN marge_periode m ON m.id_etude = ch.id_etude
 WHERE ch.id_etude = 15032
   AND ch.type IN ('RPRIM','RSEC','PRODUCTION')
   AND m.id_calcul = 101
   AND m.numero_periode = 1
)
SELECT sum(valeur)
  FROM pt_chron_res_u pt
 WHERE EXISTS (SELECT 1
                 FROM t
                WHERE t.id_chron_res_u = pt.id_chron_res_u
                  AND pt.date_res_u >= t.date_debut
                  AND pt.date_res_u <  t.date_fin)
Faire 15 fois la même requête dans une boucle n'est pas optimal non plus, que donne la requête réécrite comme ça pour les 15 périodes ? (déjà en terme de pertinance de résultat)
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
WITH t AS (
SELECT ch.id_chron_res_u, m.date_debut, m.date_fin, m.numero_periode
  FROM chron_res_u ch
  JOIN marge_periode m ON m.id_etude = ch.id_etude
 WHERE ch.id_etude = 15032
   AND ch.type IN ('RPRIM','RSEC','PRODUCTION')
   AND m.id_calcul = 101
   AND m.numero_periode BETWEEN 1 AND 15
)
SELECT m.numero_periode, sum(pt.valeur)
  FROM pt_chron_res_u pt
  JOIN t  ON t.id_chron_res_u = pt.id_chron_res_u
         AND pt.date_res_u   >= t.date_debut
         AND pt.date_res_u   <  t.date_fin
 GROUP BY m.numero_periode
Il faudrait aussi préciser la version de la base.
skuatamad est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 03/12/2012, 14h10   #3
erox44
Membre actif
 
Homme
Développeur Web
Inscription : avril 2007
Messages : 360
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 24
Localisation : France, Loire Atlantique (Pays de la Loire)

Informations professionnelles :
Activité : Développeur Web

Informations forums :
Inscription : avril 2007
Messages : 360
Points : 166
Points : 166
Salut, je vais essayer de choper le plan sous un autre format, pour ce qui est de la base, on est sous du oracle 10g.
__________________
L'intelligence c'est comme la confiture, moins tu en as , plus tu l'étales...
erox44 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/12/2012, 14h15   #4
erox44
Membre actif
 
Homme
Développeur Web
Inscription : avril 2007
Messages : 360
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 24
Localisation : France, Loire Atlantique (Pays de la Loire)

Informations professionnelles :
Activité : Développeur Web

Informations forums :
Inscription : avril 2007
Messages : 360
Points : 166
Points : 166
Ok donc , pour les requetes que tu m'as proposé, la 1ere donne le bon résultat, mais en 320s, et la 2e, donne les bons résultats, en 14s.

Du coup pour l'instant je vais surement partir sur la seconde et revoir le code applicatif derriere.


merci en tout cas :b
__________________
L'intelligence c'est comme la confiture, moins tu en as , plus tu l'étales...
erox44 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/12/2012, 15h51   #5
skuatamad
Expert Confirmé
 
Inscription : août 2008
Messages : 1 690
Détails du profil
Informations forums :
Inscription : août 2008
Messages : 1 690
Points : 2 812
Points : 2 812
Faire un tkprof de la trace étendue serait intéressant.

Il est possible qu'un index couvrant puisse améliorer les perfs si le tkprof met en évidence une contention sur la table PT_CHRON_RES_U.
Code :
CREATE INDEX IDX_CHRON_RES_id_date_val ON PT_CHRON_RES_U (id_chron_res_u, date_res_u, valeur)
Après 14sec peut être largement acceptable en fonction de l'utilisation, sinon le tkprof ainsi que la version + license permettront d'identifier d'autres directions/solutions envisageables.
skuatamad est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Cette discussion est résolue.
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 23h34.


 
 
 
 
Partenaires

Hébergement Web