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

SQL Oracle Discussion :

[11g] Performance Update avec select au niveau du set


Sujet :

SQL Oracle

  1. #1
    Candidat au Club
    Homme Profil pro
    Architecte technique
    Inscrit en
    Juin 2012
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2012
    Messages : 11
    Points : 4
    Points
    4
    Par défaut [11g] Performance Update avec select au niveau du set
    Bonjour,

    j'ai un gros problème de performance au niveau d'une de mes requêtes update qui comprend un select à l'interieur du set, au niveau du cout de la requête c une catastrophe mais je ne sais pas comment faire autrement...

    voici la 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
    UPDATE m2oPointComptage pds
    SET m2oDateRaccorde =
      ( SELECT DISTINCT first_value(e.m2oDateDerRx) over (partition BY pds.sysId order by e.sysUpdTime)
      FROM m2oCompteur cpt,
        m2oEquipement eq,
        m2oHrNbRecepCr e
      WHERE e.m2oTraite        = 'N'
      AND e.m2oIdEquipement    = eq.m2oAdresseRadio
      AND e.m2oTypeDeTrame     = '3'
      AND eq.sysClass          = 'm2oModule'
      AND eq.m2oTechno         = 'HR'
      AND cpt.sysId            = eq.m2ocompteur_id
      AND pds.sysId            = cpt.m2opointcomptage_id
      AND e.m2oDateDerRx      IS NOT NULL
      AND pds.m2oDateRaccorde IS NULL
      )
    WHERE pds.m2oDateRaccorde IS NULL
    AND EXISTS
      (SELECT 1
      FROM m2oCompteur cpt,
        m2oEquipement eq,
        m2oHrNbRecepCr e
      WHERE e.m2oTraite     = 'N'
      AND e.m2oIdEquipement = eq.m2oAdresseRadio
      AND e.m2oTypeDeTrame  = '3'
      AND eq.sysClass       = 'm2oModule'
      AND eq.m2oTechno      = 'HR'
      AND cpt.sysId         = eq.m2ocompteur_id
      AND pds.sysId         = cpt.m2opointcomptage_id
      AND e.m2oDateDerRx   IS NOT NULL
      )
    j'ai ajouté cette requête sql et le plan d'exécution fourni par sql developper en pièces jointes.

    Pour info les champs sysid sont les clefs primaires de mes tables.
    J'ai essayé de créer tous les index possibles mais je pense que je suis arrivé au bout de cette possibilité... :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    CREATE INDEX m2ohrnbrecepcr_i1 ON M2OHRNBRECEPCR(M2OTRAITE, M2OIDCR, M2OIDEQUIPEMENT) TABLESPACE INDX;
    CREATE INDEX m2oequipement_i1 ON M2OEQUIPEMENT(M2OADRESSERADIO, M2OTECHNO, SYSCLASS) TABLESPACE INDX;
    CREATE INDEX m2ohrnbrecepcr_i1 ON M2OHRNBRECEPCR(M2OIDEQUIPEMENT, M2OIDCR, M2OTRAITE) TABLESPACE INDX;
    CREATE INDEX CI4B2EE1C72FE0CBDA ON M2OCOMPTEUR(M2OPOINTCOMPTAGE_ID)
    Que faut-il que je fasse ? il doit bien avoir un autre moyen d'écrire cette requête update...
    Ou est-ce qu'il faut que passe en pl/sql avec un curseur ?

    please help !
    merci d'avance,
    Renaud
    Fichiers attachés Fichiers attachés

  2. #2
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 802
    Points
    30 802
    Par défaut
    Un autre moyen que de passer par un curseur est de passer par une table temporaire.
    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
    CREATE GLOBAL TEMPORARY TABLE tt_travail
    AS  SELECT  id
            ,   valeur1
            ,   valeur2
        FROM    marequete_set
    ;
    UPDATE  matable tbl
    SET (   valeur1
        ,   valeur2
        =   (   SELECT  tmp.valeur1
                    ,   tmp.valeur2
                FROM    tt_travail  tmp
                WHERE   tmp.id = tbl.id
            )
    WHERE   EXISTS
            (   SELECT  1
                FROM    tt_travail  sel
                WHERE   sel.id = tbl.id
            )
    ;
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  3. #3
    Candidat au Club
    Homme Profil pro
    Architecte technique
    Inscrit en
    Juin 2012
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2012
    Messages : 11
    Points : 4
    Points
    4
    Par défaut
    merci pour l'idée, en effet un collègue m'a déjà proposé de faire avec la création d'une table (je ne connaissais pas la notion de table temporaire, je v regarder ce que c'est).
    peux-tu m'expliquer en quoi cela peux me faire gagner du temps ? est-ce que dans mon premier exemple oracle ré-exécute la requête qui est dans le "set" à chaque occurrence présente dans le "where exists" ?

    N'existe-t-il pas un moyen de faire une jointure entre ma requête présente dans le "set" et celle dans le "where exists" ?

    j'ai également une question sur les index, je remarque que lorsque la condition sur la colonne est 'is null' or 'is not null', Oracle n'utilise pas l'index présent sur la colonne, je ne comprends pas pourquoi ?

    merci beaucoup pour votre aide.

  4. #4
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 947
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 947
    Points : 5 846
    Points
    5 846
    Par défaut
    Utilise MERGE pour éviter la partie EXISTS de la requête

  5. #5
    Candidat au Club
    Homme Profil pro
    Architecte technique
    Inscrit en
    Juin 2012
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2012
    Messages : 11
    Points : 4
    Points
    4
    Par défaut
    merci skuatamad, effectivement je ne connaissais pas l'instruction MERGE, ça me paraît assez intéressant pour notre cas.

    nous allons étudier ça.

    merci pour votre aide.

  6. #6
    Membre averti
    Inscrit en
    Novembre 2002
    Messages
    549
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 549
    Points : 436
    Points
    436
    Par défaut
    Citation Envoyé par skuatamad Voir le message
    Utilise MERGE pour éviter la partie EXISTS de la requête
    +1 - sur la version 11g, nous avons grandement optimiser des UPDATE avec une sous-requête avec un MERGE WHEN MATCHED - belle surprise de la 11g !
    PpPool

  7. #7
    Candidat au Club
    Homme Profil pro
    Architecte technique
    Inscrit en
    Juin 2012
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2012
    Messages : 11
    Points : 4
    Points
    4
    Par défaut
    grand merci skuatamad, nous avons divisé par 100 le temps d'exécution en passant par le MERGE

    merci à tous pour votre aide.

  8. #8
    Membre expérimenté

    Homme Profil pro
    Inscrit en
    Mars 2010
    Messages
    536
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 536
    Points : 1 359
    Points
    1 359
    Par défaut
    Citation Envoyé par rcb73 Voir le message
    grand merci skuatamad, nous avons divisé par 100 le temps d'exécution en passant par le MERGE

    merci à tous pour votre aide.
    Pour que votre question nous serve à nous tous, je vous saurai gré de bien vouloir faire ceci

    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
     
    explain plan for
    UPDATE m2oPointComptage pds
    SET m2oDateRaccorde =
      ( SELECT DISTINCT first_value(e.m2oDateDerRx) over (partition BY pds.sysId ORDER BY e.sysUpdTime)
      FROM m2oCompteur cpt,
        m2oEquipement eq,
        m2oHrNbRecepCr e
      WHERE e.m2oTraite        = 'N'
      AND e.m2oIdEquipement    = eq.m2oAdresseRadio
      AND e.m2oTypeDeTrame     = '3'
      AND eq.sysClass          = 'm2oModule'
      AND eq.m2oTechno         = 'HR'
      AND cpt.sysId            = eq.m2ocompteur_id
      AND pds.sysId            = cpt.m2opointcomptage_id
      AND e.m2oDateDerRx      IS NOT NULL
      AND pds.m2oDateRaccorde IS NULL
      )
    WHERE pds.m2oDateRaccorde IS NULL
    AND EXISTS
      (SELECT 1
      FROM m2oCompteur cpt,
        m2oEquipement eq,
        m2oHrNbRecepCr e
      WHERE e.m2oTraite     = 'N'
      AND e.m2oIdEquipement = eq.m2oAdresseRadio
      AND e.m2oTypeDeTrame  = '3'
      AND eq.sysClass       = 'm2oModule'
      AND eq.m2oTechno      = 'HR'
      AND cpt.sysId         = eq.m2ocompteur_id
      AND pds.sysId         = cpt.m2opointcomptage_id
      AND e.m2oDateDerRx   IS NOT NULL
      );
     
    select * from table(dbms_xplan.display);
    et aussi ceci (afin de pouvoir faire une comparaison)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    explain plan for
    MERGE into
           m2oPointComptage pds
    ....
    ;
     
    select * from table(dbms_xplan.display);
    et postez ici les deux plans d'exécution pour que l'on puisse comparer la différence.
    Bien Respectueusement
    www.hourim.wordpress.com

    "Ce qui se conçoit bien s'énonce clairement"

  9. #9
    Candidat au Club
    Homme Profil pro
    Sleep Working Engeneer
    Inscrit en
    Juin 2012
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Sleep Working Engeneer

    Informations forums :
    Inscription : Juin 2012
    Messages : 2
    Points : 2
    Points
    2
    Par défaut
    Inspiré de merge, j'essaie d'optimiser mes requêtes update .
    Voici la requete :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    merge into m2oEquipement eq 
    using ( select distinct eq.sysId eqSysId, first_value(e.m2oDateDerRx) over (partition by eq.m2oAdresseRadio order by e.sysUpdTime) m2oDateDerRx
    from m2oEquipement eq, m2oHrNbRecepCr e 
    where e.m2oTraite = 'N' 
    and e.m2oIdEquipement = eq.m2oAdresseRadio 
    and e.m2oTypeDeTrame = '3' 
    and e.m2oDateDerRx is not null 
    and eq.m2oDateRaccorde IS NULL 
    and eq.sysClass = 'm2oModule' 
    and eq.m2oTechno = 'HR' 
    and eq.m2oReleve != 'WB' ) tmp
    on ( eq.sysId = tmp.eqSysId )
    when matched then 
    update set eq.m2oDateRaccorde = tmp.m2oDateDerRx ;
    Mais dans SQL Developper, j'ai toujours cette erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Erreur SQL : Il n'y a plus de données à lire dans le socket
    J'ai cherché un peu sur internet mais je ne trouve pas d'information sur ce type d'erreur.
    Est-ce qu'il y a des conditions pour utiliser merge?

    Merci d'avance
    Nam

  10. #10
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

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

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Affichez toujours le numéro d’erreur Oracle. Quelle version d’Oracle utilisez vous ?

  11. #11
    Candidat au Club
    Homme Profil pro
    Sleep Working Engeneer
    Inscrit en
    Juin 2012
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Sleep Working Engeneer

    Informations forums :
    Inscription : Juin 2012
    Messages : 2
    Points : 2
    Points
    2
    Par défaut
    C'est ça le problème. C'est tout ce que j'ai comme message d'erreur quand je test cette requête dans SQL Developper.
    Je n'ai pas de numéro d’erreur Oracle.
    Ma version d'Oracle est : 11.2.0.1.0.

  12. #12
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

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

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Exécutez votre requête en sqlplus.

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

Discussions similaires

  1. Requête update avec select imrbiqué
    Par Woufeigh dans le forum Requêtes
    Réponses: 1
    Dernier message: 05/05/2008, 00h43
  2. Requête Update avec Select.
    Par franzarelli dans le forum Langage SQL
    Réponses: 1
    Dernier message: 25/03/2008, 05h33
  3. Update avec Select : je n'y arrive pas.
    Par marye77 dans le forum Langage SQL
    Réponses: 15
    Dernier message: 22/02/2008, 16h51
  4. UPDATE avec SELECT sur la même table
    Par Invité dans le forum Langage SQL
    Réponses: 7
    Dernier message: 07/12/2007, 03h39
  5. Requete Update avec Select imbriqué: etrange resultat!
    Par corentone dans le forum Langage SQL
    Réponses: 3
    Dernier message: 13/08/2007, 15h05

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