Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 5 sur 5
  1. #1
    Membre actif
    Homme Profil pro
    Développeur Web
    Inscrit en
    avril 2007
    Messages
    451
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : avril 2007
    Messages : 451
    Points : 169
    Points
    169

    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...

  2. #2
    Expert Confirmé
    Inscrit en
    août 2008
    Messages
    2 137
    Détails du profil
    Informations forums :
    Inscription : août 2008
    Messages : 2 137
    Points : 3 733
    Points
    3 733

    Par défaut

    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.

  3. #3
    Membre actif
    Homme Profil pro
    Développeur Web
    Inscrit en
    avril 2007
    Messages
    451
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : avril 2007
    Messages : 451
    Points : 169
    Points
    169

    Par défaut

    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...

  4. #4
    Membre actif
    Homme Profil pro
    Développeur Web
    Inscrit en
    avril 2007
    Messages
    451
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : avril 2007
    Messages : 451
    Points : 169
    Points
    169

    Par défaut

    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...

  5. #5
    Expert Confirmé
    Inscrit en
    août 2008
    Messages
    2 137
    Détails du profil
    Informations forums :
    Inscription : août 2008
    Messages : 2 137
    Points : 3 733
    Points
    3 733

    Par défaut

    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.

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

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •