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 :

[PL/SQL] Temps de mis à jour trop long


Sujet :

SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Décembre 2005
    Messages
    35
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 35
    Par défaut [PL/SQL] Temps de mis à jour trop long
    Bonjour à tou(te)s,

    Environnement : Oracle 8i/Toad/Unix

    J'essaye de mettre à jour environ 800.000 lignes dans une table de 17.000.000 de lignes environ. La mise à jour s'effectue suivant deux champs différents mais, sur des lignes comprises dans le même intervalle de temps. Pour le faire, j'utilise 2 curseurs A et B : le curseur A met à jour plusieurs champs et le curseur A un seul champ (déjà mis à jour par le curseur A => écrasement le cas échéant).
    Le curseur A retourne plus de ligne que le curseur B; les deux curseurs retournent plus de lignes que le nombre de ligne de la plage à mettre à jour. J'ai plusieurs index (Bitmap et B-tree) sur la table; dont des index sur les deux clés de mise à jour. Le curseur B est beaucoup plus complexe que le curseur A

    Mon problème est le suivant : la mise à jour avec le curseur A prend entre 18mn et 1h30 en fonction de la charge du réseau. Tandis qu'avec le curseur B, j'en ai pour 18h minimum!!!
    Toutes les pistes pour comprendre d'où vient le problèmes sont les bienvenues.

    Merci pour votre aide

    Curseur A

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT VR, PA, VK,
         AN,VER, SEQ_P,
         SEQ_V,  LPAD(SUBSTR(SIR,1,14),14,'0') SIR,
         IND,ABREGE,  SUBSTR(NIVEAU,1,4) NIVEAU,
         AUS
        FROM  CORR  
        ORDER BY VER


    Curseur B
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT AN,ABREGE
        FROM   CORR C
        WHERE  LOE IS NULL
        AND    AUS=(SELECT MAX(AUS)
                 FROM CORR C2
            WHERE C2.ANLAGE=C.ANLAGE
           )

  2. #2
    Membre Expert Avatar de Garuda
    Homme Profil pro
    Chef de projet / Urbaniste SI
    Inscrit en
    Juin 2007
    Messages
    1 285
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Chef de projet / Urbaniste SI
    Secteur : Bâtiment

    Informations forums :
    Inscription : Juin 2007
    Messages : 1 285
    Par défaut
    ET ton code ???

  3. #3
    Membre averti
    Inscrit en
    Décembre 2005
    Messages
    35
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 35
    Par défaut
    Citation Envoyé par Garuda
    ET ton code ???
    Désolée pour l'oubli

    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
     
    OPEN A();
          LOOP
             BEGIN
                FETCH A INTO ListVer;
                EXIT WHEN A%NOTFOUND;
                lu := lu + 1;
                traite := lu; 
     
        	    UPDATE AGR SET VR=ListVer.VR,
    				    PA=ListVer.PA,
     				    VK=ListVer.VK,
    				    SEQ_P =ListVer.SEQ_P ,
    				    SEQ_V=ListVer.SEQ_V,
    				    SIR=ListVer.SIR,
    				    IND=ListVer.IND,
    				    ABREGE=ListVer.ABREGE,
    				    NIVEAU=ListVer.NIVEAU
     	    WHERE VER=ListVer.VER
    	              AND   APPL IN ('S','Q')
    	              AND ( ( MOIS_R >= pMOIS  AND  ANNEE_R = pANNEE)
    			        OR
    					( ANNEE_R > pANNEE )
    				    )
    				   AND ( (ANNEE_R < 2050)
    				         OR
    				  	     (ANNEE_R = 2050) AND (MOIS_R < 99)
    				       );
     
    	ecrit := ecrit + 1;
            IF MOD (ecrit, 10) = 0 THEN COMMIT; END IF;
       EXCEPTION
                WHEN OTHERS
                THEN
                   alim_generale.msg (nom2, phase, 'LOOP', 'SG'||SQLCODE, ListVer.vertrag);
             END;
       END LOOP;
    CLOSE A;
     
    	  lu:=0;
     
     
    OPEN B();
          LOOP
             BEGIN
                FETCH BINTO ListB;
                EXIT WHEN B%NOTFOUND;
                lu := lu + 1;
                traite := lu;
     
        	    UPDATE G_AGR SET   ABREGE=ListB.ABREGE
    	    WHERE AN=ListB.AN
    	              AND ( ( MOIS_R >= pMOIS  AND  ANNEE_R = pANNEE)
    			        OR
    					( ANNEE_R > pANNEE )
    				    )
    				   AND ( (ANNEE_R < 2050)
    				         OR
    				  	     (ANNEE_R = 2050) AND (MOIS_ < 99)
    				       );
     
    	          lu := lu + 1;
                IF MOD (lu, 100) = 0 THEN COMMIT; END IF;
      EXCEPTION
                WHEN OTHERS
                THEN
                   alim_generale.msg (nom2, phase, 'LOOP', 'AB'||SQLCODE, ListB.AN);
          END;
       END LOOP;
    CLOSE B;
    Note : dans la période choise, le champ 'APPL' est toujours dans ('S','Q')

  4. #4
    McM
    McM est déconnecté
    Expert confirmé

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Billets dans le blog
    4
    Par défaut
    Tu peux donner les UPDATE ?
    Ensuite, faut voir les trigger sur la table, et surtout les Index bitmap.. ça peut locker à donf ces trucs.

    Qu'est ce qui est long, les UPDATES ou les curseurs ?

    Pour info un LPAD fait un SUBSTR automatique
    tu peux remplacer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    LPAD(SUBSTR(SIR,1,14),14,'0') SIR 
    par 
    LPAD(SIR,14,'0') SIR

  5. #5
    Membre averti
    Inscrit en
    Décembre 2005
    Messages
    35
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 35
    Par défaut
    Citation Envoyé par McM
    Tu peux donner les UPDATE ?
    Ensuite, faut voir les trigger sur la table, et surtout les Index bitmap.. ça peut locker à donf ces trucs.

    Qu'est ce qui est long, les UPDATES ou les curseurs ?

    Pour info un LPAD fait un SUBSTR automatique
    tu peux remplacer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    LPAD(SUBSTR(SIR,1,14),14,'0') SIR 
    par 
    LPAD(SIR,14,'0') SIR
    Merci. je met à jour le code.

    A priori, c'est le second update qui est lent (celui qui utilise le curseur B) (J'ai mis des relève de temps entre les deux update afin de voir lequel prend du temps.). Lorsque j'exécute le script des curseurs, j'ai des résultats très rapidement. Il n'y a pas de trigger sur la table (sur aucune des tables de la BDD).
    J'ai aussi pensé aux index BITMAP . Il y a en 1 sur le champ "ABREGE" :
    - j'ai essayé de tous les supprimer avant la mise à jour sans résultat probant
    - qu'est ce qui expliquerait que les Index Bitmap ne posent pas de problème lors du premier update?

  6. #6
    Membre Expert Avatar de Garuda
    Homme Profil pro
    Chef de projet / Urbaniste SI
    Inscrit en
    Juin 2007
    Messages
    1 285
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Chef de projet / Urbaniste SI
    Secteur : Bâtiment

    Informations forums :
    Inscription : Juin 2007
    Messages : 1 285
    Par défaut
    REMARQUE : il te manque un commit en sortie de boucle (apres le close A) , des fois qu'il en reste à commiter (Nb de mises à jour pas multiple de 10) !!!!

    Idem pour B


    ET fais des boucles de curseur , c'est + lisible !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    FOR C1 in (select .....) LOOP
     
    .....
     
    END LOOP

  7. #7
    McM
    McM est déconnecté
    Expert confirmé

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Billets dans le blog
    4
    Par défaut
    Je sais pas si c'est mieux (vu la volumétrie) de ne faire qu'un seul update plutôt qu'une boucle.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     UPDATE AGR 
    SET (vr, pa, vk, seq_p, seq_v, sir, ind, abrege, niveau)
    	= (SELECT vr, pa, vk, seq_p, seq_v, LPAD(sir,14,'0') sir,
    		ind, abrege, SUBSTR(niveau,1,4) niveau
    	FROM  CORR  
    	WHERE ver = a.ver)
    WHERE appl IN ('S','Q')
    AND ( (mois_r >= pmois  AND annee_r = pannee) OR( annee_r > pannee ))	
    AND ( (annee_r < 2050) OR (annee_r = 2050) AND (mois_r < 99))
    AND EXISTS (SELECT 1 FROM CORR WHERE ver = a.ver);

  8. #8
    Membre averti
    Inscrit en
    Décembre 2005
    Messages
    35
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 35
    Par défaut
    Merci à tous les deux.
    J'ajoute les commit la où il en manque. McM, est ce qu'un seul update ne re-rxécute pas la sous requête pour chaque ligne de la table à mettre à jour? Idem pour une boucle de curseur garuda. (Désolée si mes questions sont stupides, je n'ai ps trouvé de tutoriel qui m'explique techniquement le curseur)

Discussions similaires

  1. Temps de traitement select trop long
    Par David79 dans le forum Requêtes
    Réponses: 1
    Dernier message: 19/05/2013, 11h37
  2. temps de chargement form trop long
    Par lovedesitaliens dans le forum C#
    Réponses: 17
    Dernier message: 02/11/2010, 10h01
  3. temps insertion fichier texte trop long
    Par developpeur71 dans le forum Windows Forms
    Réponses: 34
    Dernier message: 16/12/2009, 14h39
  4. Proc ASSIGN temps d'exécution très, trop long
    Par bdbdb dans le forum SAS STAT
    Réponses: 1
    Dernier message: 02/03/2009, 16h39
  5. [VB6]Message d'erreur si le temps d'exécution est trop long
    Par Asdorve dans le forum VB 6 et antérieur
    Réponses: 16
    Dernier message: 14/09/2006, 16h43

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