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

PL/SQL Oracle Discussion :

Croisement 2 grosses tables -> perfs en chute libre


Sujet :

PL/SQL Oracle

  1. #1
    Membre averti
    Inscrit en
    Août 2008
    Messages
    19
    Détails du profil
    Informations personnelles :
    Âge : 52

    Informations forums :
    Inscription : Août 2008
    Messages : 19
    Par défaut Croisement 2 grosses tables -> perfs en chute libre
    Bonjour,

    j'ai un problème de performances sur une procédure pl/sql qui me croise les données de 2 grosses tables pour les mettre dans une 3ème.

    la 1ere table s'appelle T_HEXACLE et contient ~20 000 000 d'enregistrements sur 4 champs.

    la 2ème table s'appelle T_HEXAVIA et contient ~2 000 000 d'enregistrements sur 33 champs.

    Ces 2 tables n'ont pas de clé primaire/unique !
    Le croisement des données se fait sur les champs "MATRICULE_VOIE" (auxquels j'ai ajouté des index)

    la 3ème table, celle qui recevra le résultat, s'appelle T_ADRESSES_SIG (et devra donc comprendre 20 000 000 d'enregistrements et 37 colonnes, 36 + un id clé primaire unique que j'ai rajouté)

    Voici ma procédure :

    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
     
    create or replace PROCEDURE PROC_FUSION_HEXA AS
      cpt NUMBER:=0;
     
      var_type_enr T_ADRESSES_SIG.TYPE_ENR%type;
      var_insee_localite T_ADRESSES_SIG.INSEE_LOCALITE%type;
      var_insee_global T_ADRESSES_SIG.INSEE_GLOBAL%type;
      var_localite T_ADRESSES_SIG.LOCALITE%type;
      var_pluridistribution T_ADRESSES_SIG.PLURIDISTRIBUTION%type;
      var_lieu_dit T_ADRESSES_SIG.LIEU_DIT%type;
      var_roudis2000 T_ADRESSES_SIG.ROUDIS2000%type;
      var_code_postal T_ADRESSES_SIG.CODE_POSTAL%type;
      var_insee_commune_admin T_ADRESSES_SIG.INSEE_COMMUNE_ADMIN%type;
      var_localite_fiab T_ADRESSES_SIG.LOCALITE_FIAB%type;
      var_maj T_ADRESSES_SIG.MAJ%type;
      var_acheminement T_ADRESSES_SIG.ACHEMINEMENT%type;
      var_matricule_voie T_ADRESSES_SIG.MATRICULE_VOIE%type;
      var_matricule_voie_s T_ADRESSES_SIG.MATRICULE_VOIE_S%type;
      var_dernier_voie T_ADRESSES_SIG.DERNIER_VOIE%type;
      var_libelle_voie T_ADRESSES_SIG.LIBELLE_VOIE%type;
      var_libelle_voie_s T_ADRESSES_SIG.LIBELLE_VOIE_S%type;
      var_type_voie T_ADRESSES_SIG.TYPE_VOIE%type;
      var_type_voie_s T_ADRESSES_SIG.TYPE_VOIE_S%type;
      var_descripteur_voie T_ADRESSES_SIG.DESCRIPTEUR_VOIE%type;
      var_descripteur_voie_s T_ADRESSES_SIG.DESCRIPTEUR_VOIE_S%type;
      var_standardisation T_ADRESSES_SIG.STANDARDISATION%type;
      var_scindage T_ADRESSES_SIG.SCINDAGE%type;
      var_borne_ii T_ADRESSES_SIG.BORNE_II%type;
      var_ext_ii T_ADRESSES_SIG.EXT_II%type;
      var_borne_is T_ADRESSES_SIG.BORNE_IS%type;
      var_ext_is T_ADRESSES_SIG.EXT_IS%type;
      var_borne_pi T_ADRESSES_SIG.BORNE_PI%type;
      var_ext_pi T_ADRESSES_SIG.EXT_PI%type;
      var_borne_ps T_ADRESSES_SIG.BORNE_PS%type;
      var_ext_ps T_ADRESSES_SIG.EXT_PS%type;
      var_roudis T_ADRESSES_SIG.ROUDIS%type;
      var_appellation T_ADRESSES_SIG.APPELLATION%type;
     
      var_num_voie T_ADRESSES_SIG.NUM_VOIE%type;
      var_extension_voie T_ADRESSES_SIG.EXTENSION_VOIE%type;
      var_cle_hexacle T_ADRESSES_SIG.CLE_HEXACLE%type;
     
    CURSOR CUR IS
      SELECT MATRICULE_VOIE, NUM_VOIE, EXTENSION_VOIE, CLE_HEXACLE FROM T_HEXACLE;
     
    CURSOR CUR2 IS
      SELECT TYPE_ENR, INSEE_LOCALITE, INSEE_GLOBAL, LOCALITE, PLURIDISTRIBUTION, LIEU_DIT, ROUDIS2000, CODE_POSTAL, INSEE_COMMUNE_ADMIN, LOCALITE_FIAB,  MAJ, ACHEMINEMENT, MATRICULE_VOIE_S, DERNIER_VOIE, LIBELLE_VOIE, LIBELLE_VOIE_S, TYPE_VOIE, TYPE_VOIE_S, DESCRIPTEUR_VOIE, DESCRIPTEUR_VOIE_S, STANDARDISATION, SCINDAGE, BORNE_II, EXT_II, BORNE_IS, EXT_IS, BORNE_PI, EXT_PI, BORNE_PS, EXT_PS, ROUDIS, APPELLATION
      FROM T_HEXAVIA WHERE MATRICULE_VOIE=var_matricule_voie AND (TYPE_ENR LIKE 'V' OR TYPE_ENR LIKE 'W');
     
    BEGIN
      DELETE FROM T_ADRESSES_SIG;
      OPEN CUR;
      loop
        FETCH CUR INTO var_matricule_voie, var_num_voie, var_extension_voie, var_cle_hexacle;
        EXIT WHEN CUR%NOTFOUND;
     
            OPEN CUR2;
            loop
              FETCH CUR2 INTO var_type_enr, var_insee_localite, var_insee_global, var_localite, var_pluridistribution, var_lieu_dit, var_roudis2000, var_code_postal, var_insee_commune_admin, var_localite_fiab, var_maj, var_acheminement, var_matricule_voie_s, var_dernier_voie, var_libelle_voie, var_libelle_voie_s, var_type_voie, var_type_voie_s, var_descripteur_voie, var_descripteur_voie_s, var_standardisation, var_scindage, var_borne_ii, var_ext_ii, var_borne_is, var_ext_is, var_borne_pi, var_ext_pi, var_borne_ps, var_ext_ps, var_roudis, var_appellation;
              EXIT WHEN CUR2%NOTFOUND;
     
              cpt:=cpt+1;
              INSERT INTO T_ADRESSES_SIG(TYPE_ENR, INSEE_LOCALITE, INSEE_GLOBAL, LOCALITE, PLURIDISTRIBUTION, LIEU_DIT, ROUDIS2000, CODE_POSTAL, INSEE_COMMUNE_ADMIN, LOCALITE_FIAB, MAJ, ACHEMINEMENT, MATRICULE_VOIE, NUM_VOIE, EXTENSION_VOIE, CLE_HEXACLE, MATRICULE_VOIE_S, DERNIER_VOIE, LIBELLE_VOIE, LIBELLE_VOIE_S, TYPE_VOIE, TYPE_VOIE_S, DESCRIPTEUR_VOIE, DESCRIPTEUR_VOIE_S, STANDARDISATION, SCINDAGE, BORNE_II, EXT_II, BORNE_IS, EXT_IS, BORNE_PI, EXT_PI, BORNE_PS, EXT_PS, ROUDIS, APPELLATION)
              VALUES(var_type_enr, var_insee_localite, var_insee_global, var_localite, var_pluridistribution, var_lieu_dit, var_roudis2000, var_code_postal, var_insee_commune_admin, var_localite_fiab, var_maj, var_acheminement, var_matricule_voie, var_num_voie, var_extension_voie, var_cle_hexacle, var_matricule_voie_s, var_dernier_voie, var_libelle_voie, var_libelle_voie_s, var_type_voie, var_type_voie_s, var_descripteur_voie, var_descripteur_voie_s, var_standardisation, var_scindage, var_borne_ii, var_ext_ii, var_borne_is, var_ext_is, var_borne_pi, var_ext_pi, var_borne_ps, var_ext_ps, var_roudis, var_appellation);
     
            end loop;
            close CUR2;
            if mod(cpt, 5000)=0 then
              COMMIT;
            end if;
      end loop;
      dbms_output.put_line('Total : ' || cpt);
      CLOSE CUR;
    END PROC_FUSION_HEXA;
    j'ai surveillé le temps d'exécution dans V_$SESSION_LONGOPS et c'est pas rassurant :
    les 100 000 1ères lignes ont été traitées en 6 minutes
    les 50 000 suivantes en 9 minutes
    les 50 000 suivantes en 13 minutes
    les 50 000 suivantes en 15 minutes
    les 50 000 suivantes en 19 minutes
    ...et le TIME_REMAINING est estimé à 70 heures (et continue de grimper !!!)

    Il s'agit d'un Oracle 11.1.0 qui tourne pourtant sur une machine de guerre (quadriprocesseur quadcore + 64Go de Ram + disques 15000rpm).

    Si vous avez des idées d'optimisation de ma procédure je suis preneur...
    Merci d'avance pour vos réponses.

  2. #2
    Membre averti
    Inscrit en
    Août 2008
    Messages
    19
    Détails du profil
    Informations personnelles :
    Âge : 52

    Informations forums :
    Inscription : Août 2008
    Messages : 19
    Par défaut
    les 50 000 suivantes en 23 minutes et reste 77 heures
    les 50 000 suivantes en 27 minutes et reste 88 heures

  3. #3
    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
    Houla, c'est pas bon comme script !! Arrête tout de suite.

    1/ Faut éviter les curseurs imbriqués sur des tables comme ça. Ca fait des allers-retours entre le moteur pl et la base.

    2/ Utilises des For LOO, c'est plus simple

    3/ Après un delete en entrée de procédure, mieux vaut faire un COMMIT, ça libère l'UNDO.

    4/ C'est sympa le "IF Mod(v_nb, 5000) = 0", mais si le curseur2 te ramène à chaque fois 3 enregistrements... tu passera jamais dans ce IF

    Voici un exemple (faut voir les colonnes et le Mod du commi.
    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
    CREATE OR REPLACE PROCEDURE PROC_FUSION_HEXA 
    AS
      cpt NUMBER:=0;
    BEGIN
     
      DELETE FROM T_ADRESSES_SIG;
      COMMIT;
     -- ou TRUNCATE TABLE T_ADRESSES_SIG;
     
      FOR r IN (SELECT matricule_voie, num_voie, extension_voie, cle_hexacle FROM T_HEXACLE)
      LOOP
     
      	 INSERT INTO T_ADRESSES_SIG(TYPE_ENR, INSEE_LOCALITE, INSEE_GLOBAL, LOCALITE, PLURIDISTRIBUTION, LIEU_DIT, ROUDIS2000, CODE_POSTAL, 
         														INSEE_COMMUNE_ADMIN, LOCALITE_FIAB, MAJ, ACHEMINEMENT, MATRICULE_VOIE, NUM_VOIE, EXTENSION_VOIE, CLE_HEXACLE, 
                                    MATRICULE_VOIE_S, DERNIER_VOIE, LIBELLE_VOIE, LIBELLE_VOIE_S, TYPE_VOIE, TYPE_VOIE_S, DESCRIPTEUR_VOIE, 
                                    DESCRIPTEUR_VOIE_S, STANDARDISATION, SCINDAGE, BORNE_II, EXT_II, BORNE_IS, EXT_IS, BORNE_PI, EXT_PI, BORNE_PS, EXT_PS,
                                    ROUDIS, APPELLATION)
        -- Ordre pas bon, et il y a peut être des données du curseur 1
         SELECT type_enr, insee_localite, insee_global, localite, pluridistribution, lieu_dit, roudis2000, code_postal, 
         				insee_commune_admin, localite_fiab,  maj, acheminement, matricule_voie_s, dernier_voie, libelle_voie, libelle_voie_s, 
                type_voie, type_voie_s, descripteur_voie, descripteur_voie_s, standardisation, scindage, borne_ii, ext_ii, borne_is, 
                ext_is, borne_pi, ext_pi, borne_ps, ext_ps, roudis, appellation
         FROM T_HEXAVIA 
         WHERE matricule_voie= r.matricule_voie 
         AND (type_enr LIKE 'V' OR TYPE_ENR LIKE 'W');
     
    		 cpt := cpt+ SQL%rowcount;
     
     
     		IF MOD(cpt, 5000)=0 
        THEN
        	COMMIT;
        END IF;
     
      END LOOP;
      DBMS_OUTPUT.PUT_LINE('Total : ' || cpt);
     
    END PROC_FUSION_HEXA;

  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
    Bon, c'était un premier débugage de code.
    Parce qu'en relisant, tu comptes avoir 20M de lignes dans ta 3ème table, alors que t'en a 20M dans la première et 2M dans la seconde, c'est si ton curseur 2 ne ramène qu'une seule ligne par matricule_voie..

    Vérifie bien sur quelques exemples ce que ça donne.

    Le meilleur moyen, c'est 1 seule requête, parce que en plus tu as mis ta grosse table en premier curseur (donc exécution de 20M d'INSERT !!)

  5. #5
    Membre averti
    Inscrit en
    Août 2008
    Messages
    19
    Détails du profil
    Informations personnelles :
    Âge : 52

    Informations forums :
    Inscription : Août 2008
    Messages : 19
    Par défaut
    pour les 20 000 000 d'enregistrement dans la 3ème table, en fait c'est un minimum mais le résultat final ne devrait pas être bien plus gros (je l'ai déjà fait tourné sur un échantillon plus petit et je suis passé de 36000 lignes à 39000 lignes).
    Mais malheureusement il s'agit donc bien d'une relation n-n si c'est ta question.

    Pour ton 1) et ton 2) ... le For r n'est-il pas un curseur implicite ?
    J'avais déjà essayé un for à la place du 2ème curseur et c'était aussi long.
    je suis revenu au curseur explicite en ayant lu que l'implicite ne libérait pas forcément bien la mémoire (ce que fait l'explicite avec le CLOSE)

    3) bonne idée

    4) comme en général le 2ème curseur ne renvoie qu'une ligne ce n'est pas gênant.

    Sinon j'ai pas trop compris dans ta modif le SELECT après le INSERT ?

  6. #6
    Expert éminent
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Par défaut
    Essaye plutôt un truc de ce genre

    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
    CREATE OR REPLACE PROCEDURE PROC_FUSION_HEXA AS
      cpt NUMBER:=0;
     
      TYPE rec_adresses IS TABLE OF t_adresses_sig%ROWTYPE;
     
      tab_adresse rec_adresses;
     
     
    CURSOR CUR IS
      SELECT type_enr, 
             insee_localite, 
    		 ...
    		 extension_voie, 
    		 cle_hexacle 
       FROM t_hexacle cle, t_hexavia via
      WHERE cle.matricule_voie=via.cle.matricule_voie 
        AND type_enr IN ('V','W');
     
    BEGIN
      EXECUTE IMMEDIATE ('TRUNCATE TABLE T_ADRESSES_SIG'); -- Plutôt que DELETE pour éviter de consommer du ROLLBACK et c'est instantanée
      OPEN CUR;
      LOOP
        FETCH cur BULK COLLECT INTO tab_adresse LIMIT 5000;
    	FOR i IN tab_adresse.FIRST..tab_adresse.LAST LOOP
          INSERT INTO T_ADRESSES_SIG(TYPE_ENR, INSEE_LOCALITE, ... ,ROUDIS, APPELLATION)
          VALUES(tab_adresse(i).TYPE_ENR,tab_adresse(i). , ... , tab_adresse(i).ROUDIS , tab_adresse(i).APPELLATION );
        END LOOP;
    	COMMIT;
        EXIT WHEN CUR%NOTFOUND;
      END LOOP;
      dbms_output.put_line('Total : ' || cpt);
      CLOSE CUR;
    END PROC_FUSION_HEXA;
    BULK COLLECT, TRUNCATE et un seul curseur permettront de sensiblement améliorer les perfs

  7. #7
    Membre averti
    Inscrit en
    Août 2008
    Messages
    19
    Détails du profil
    Informations personnelles :
    Âge : 52

    Informations forums :
    Inscription : Août 2008
    Messages : 19
    Par défaut
    Bon j'ai relancé la procédure avec ta méthode.
    Mais pour l'instant la durée de l'opération semble quasi identique (6 minutes pour les 100 000 premières lignes).
    Je vais la laisser tourner cette nuit et on verra bien
    A demain

  8. #8
    Membre averti
    Inscrit en
    Août 2008
    Messages
    19
    Détails du profil
    Informations personnelles :
    Âge : 52

    Informations forums :
    Inscription : Août 2008
    Messages : 19
    Par défaut
    Bilan après une quinzaine d'heures :
    1 115 000 lignes traitées (sur les ~20 000 000)
    et selon V_$SESSION_LONGOPS il reste .... 10 jours

  9. #9
    Expert éminent
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Par défaut
    et v$session_wait ça dit quoi ? T'a bien un index sur T_HEXAVIA (matricule_voie, type_enr) ?

    C'est quoi que tu as essayé exactement ?

  10. #10
    Membre averti
    Inscrit en
    Août 2008
    Messages
    19
    Détails du profil
    Informations personnelles :
    Âge : 52

    Informations forums :
    Inscription : Août 2008
    Messages : 19
    Par défaut
    1) Qu'est ce que tu veux voir dans v$session_wait ?

    2) oui il y a bien des index sur matricule_voie dans les 2 tables et sur type_enr dans hexavia

    3) J'ai refait ma procédure à ta sauce et j'ai lancé son exécution hier soir

    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
    create or replace PROCEDURE PROC_FUSION_HEXA_TEST AS
      cpt NUMBER:=0;
     
      TYPE rec_adresses IS TABLE OF t_adresses_sig%ROWTYPE;
     
      tab_adresse rec_adresses;
     
     
    CURSOR CUR IS
      SELECT 1,VIA.TYPE_ENR, VIA.INSEE_LOCALITE, VIA.INSEE_GLOBAL, VIA.LOCALITE, VIA.PLURIDISTRIBUTION, VIA.LIEU_DIT, VIA.ROUDIS2000, VIA.CODE_POSTAL, VIA.INSEE_COMMUNE_ADMIN, VIA.LOCALITE_FIAB,  VIA.MAJ, VIA.ACHEMINEMENT, CLE.MATRICULE_VOIE, CLE.NUM_VOIE, CLE.EXTENSION_VOIE, CLE.CLE_HEXACLE, VIA.MATRICULE_VOIE_S, VIA.DERNIER_VOIE, VIA.LIBELLE_VOIE, VIA.LIBELLE_VOIE_S, VIA.TYPE_VOIE, VIA.TYPE_VOIE_S, VIA.DESCRIPTEUR_VOIE, VIA.DESCRIPTEUR_VOIE_S, VIA.STANDARDISATION, VIA.SCINDAGE, VIA.BORNE_II, VIA.EXT_II, VIA.BORNE_IS, VIA.EXT_IS, VIA.BORNE_PI, VIA.EXT_PI, VIA.BORNE_PS, VIA.EXT_PS, VIA.ROUDIS, VIA.APPELLATION
       FROM t_hexacle cle, t_hexavia via
      WHERE cle.matricule_voie=via.matricule_voie 
        AND type_enr IN ('V','W');
     
    BEGIN
      EXECUTE IMMEDIATE ('TRUNCATE TABLE T_ADRESSES_SIG'); -- Plutôt que DELETE pour éviter de consommer du ROLLBACK et c'est instantanée
      OPEN CUR;
      LOOP
        FETCH cur BULK COLLECT INTO tab_adresse LIMIT 5000;
    	FOR i IN tab_adresse.FIRST..tab_adresse.LAST
            LOOP
              INSERT INTO T_ADRESSES_SIG(TYPE_ENR, INSEE_LOCALITE, INSEE_GLOBAL, LOCALITE, PLURIDISTRIBUTION, LIEU_DIT, ROUDIS2000, CODE_POSTAL, INSEE_COMMUNE_ADMIN, LOCALITE_FIAB, MAJ, ACHEMINEMENT, MATRICULE_VOIE, NUM_VOIE, EXTENSION_VOIE, CLE_HEXACLE, MATRICULE_VOIE_S, DERNIER_VOIE, LIBELLE_VOIE, LIBELLE_VOIE_S, TYPE_VOIE, TYPE_VOIE_S, DESCRIPTEUR_VOIE, DESCRIPTEUR_VOIE_S, STANDARDISATION, SCINDAGE, BORNE_II, EXT_II, BORNE_IS, EXT_IS, BORNE_PI, EXT_PI, BORNE_PS, EXT_PS, ROUDIS, APPELLATION)
              VALUES(tab_adresse(i).TYPE_ENR, tab_adresse(i).INSEE_LOCALITE, tab_adresse(i).INSEE_GLOBAL, tab_adresse(i).LOCALITE, tab_adresse(i).PLURIDISTRIBUTION, tab_adresse(i).LIEU_DIT, tab_adresse(i).ROUDIS2000, tab_adresse(i).CODE_POSTAL, tab_adresse(i).INSEE_COMMUNE_ADMIN, tab_adresse(i).LOCALITE_FIAB, tab_adresse(i).MAJ, tab_adresse(i).ACHEMINEMENT, tab_adresse(i).MATRICULE_VOIE, tab_adresse(i).NUM_VOIE, tab_adresse(i).EXTENSION_VOIE, tab_adresse(i).CLE_HEXACLE, tab_adresse(i).MATRICULE_VOIE_S, tab_adresse(i).DERNIER_VOIE, tab_adresse(i).LIBELLE_VOIE, tab_adresse(i).LIBELLE_VOIE_S, tab_adresse(i).TYPE_VOIE, tab_adresse(i).TYPE_VOIE_S, tab_adresse(i).DESCRIPTEUR_VOIE, tab_adresse(i).DESCRIPTEUR_VOIE_S, tab_adresse(i).STANDARDISATION, tab_adresse(i).SCINDAGE, tab_adresse(i).BORNE_II, tab_adresse(i).EXT_II, tab_adresse(i).BORNE_IS, tab_adresse(i).EXT_IS, tab_adresse(i).BORNE_PI, tab_adresse(i).EXT_PI, tab_adresse(i).BORNE_PS, tab_adresse(i).EXT_PS, tab_adresse(i).ROUDIS , tab_adresse(i).APPELLATION );
        END LOOP;
    	COMMIT;
        EXIT WHEN CUR%NOTFOUND;
      END LOOP;
      dbms_output.put_line('Total : ' || cpt);
      CLOSE CUR;
    END PROC_FUSION_HEXA_TEST;
    Bon, je vous fait batailler, mais peut-être qu'il n'y pas de véritable solution pour vraiment améliorer cette requête ?
    Peut-être peut-on optimiser un peu la configuration d'oracle ou de ma base (taille des tablespace ...?)

    PS : on est est maintenant à 1 220 000 lignes traitées en 17h30 d'exécution et avec un temps estimé restant de 260 heures (10.85 jours)

  11. #11
    Expert éminent
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Par défaut
    1) les événements d'attente de ta session
    2) il en faut un sur les 2 colonnes de hexavia

    Peut-être peut-on optimiser un peu la configuration d'oracle ou de ma base (taille des tablespace ...?)
    Pour le savoir faut regarder v$system_event et v$session_wait pour voir ce qui coince.

    Je pense qu'il faut réduire la fréquence des commits aussi... j'te sens bien parti pour avoir un snapshot too old

  12. #12
    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
    Tiens ça me rappelle un vieux post : On a cherché comme des fous pour voir que c'était la table de destination (T_ADRESSES_SIG) qui avait un next_extend à 64Ko, du coup les insert étaient sans arrêt en attente de l'augmentation des segments de la table.

  13. #13
    Membre averti
    Inscrit en
    Août 2008
    Messages
    19
    Détails du profil
    Informations personnelles :
    Âge : 52

    Informations forums :
    Inscription : Août 2008
    Messages : 19
    Par défaut
    Mon script continue son exécution (1 810 000 lignes en 39 heures).
    Selon v_$session_longops il reste 15.6 jours...

    Pour vous aider, voici le script de création de ma table de destination :

    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
      CREATE TABLE "PUSRDWH01"."T_ADRESSES_SIG" 
       (	"ID_ADRESSES_SIG" NUMBER NOT NULL ENABLE, 
    	"TYPE_ENR" VARCHAR2(1 BYTE), 
    	"INSEE_LOCALITE" VARCHAR2(5 BYTE), 
    	"INSEE_GLOBAL" VARCHAR2(5 BYTE), 
    	"LOCALITE" VARCHAR2(38 BYTE), 
    	"PLURIDISTRIBUTION" VARCHAR2(1 BYTE), 
    	"LIEU_DIT" VARCHAR2(1 BYTE), 
    	"ROUDIS2000" VARCHAR2(1 BYTE), 
    	"CODE_POSTAL" VARCHAR2(5 BYTE), 
    	"INSEE_COMMUNE_ADMIN" VARCHAR2(5 BYTE), 
    	"LOCALITE_FIAB" VARCHAR2(1 BYTE), 
    	"MAJ" VARCHAR2(1 BYTE), 
    	"ACHEMINEMENT" VARCHAR2(32 BYTE), 
    	"MATRICULE_VOIE" VARCHAR2(8 BYTE), 
    	"NUM_VOIE" VARCHAR2(4 BYTE), 
    	"EXTENSION_VOIE" VARCHAR2(1 BYTE), 
    	"CLE_HEXACLE" VARCHAR2(10 BYTE), 
    	"MATRICULE_VOIE_S" VARCHAR2(8 BYTE), 
    	"DERNIER_VOIE" VARCHAR2(20 BYTE), 
    	"LIBELLE_VOIE" VARCHAR2(32 BYTE), 
    	"LIBELLE_VOIE_S" VARCHAR2(32 BYTE), 
    	"TYPE_VOIE" VARCHAR2(4 BYTE), 
    	"TYPE_VOIE_S" VARCHAR2(4 BYTE), 
    	"DESCRIPTEUR_VOIE" VARCHAR2(10 BYTE), 
    	"DESCRIPTEUR_VOIE_S" VARCHAR2(10 BYTE), 
    	"STANDARDISATION" VARCHAR2(1 BYTE), 
    	"SCINDAGE" VARCHAR2(1 BYTE), 
    	"BORNE_II" VARCHAR2(4 BYTE), 
    	"EXT_II" VARCHAR2(1 BYTE), 
    	"BORNE_IS" VARCHAR2(4 BYTE), 
    	"EXT_IS" VARCHAR2(1 BYTE), 
    	"BORNE_PI" VARCHAR2(4 BYTE), 
    	"EXT_PI" VARCHAR2(1 BYTE), 
    	"BORNE_PS" VARCHAR2(4 BYTE), 
    	"EXT_PS" VARCHAR2(1 BYTE), 
    	"ROUDIS" VARCHAR2(5 BYTE), 
    	"APPELLATION" VARCHAR2(1 BYTE), 
    	 CONSTRAINT "T_ADRESSES_SIG_PK" PRIMARY KEY ("ID_ADRESSES_SIG")
      USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
      STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
      PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
      TABLESPACE "PTBSDWH01"  ENABLE
       ) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
      STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
      PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
      TABLESPACE "PTBSDWH01" ;
     
      CREATE OR REPLACE TRIGGER "PUSRDWH01"."TRI_ADRESSES_SIG" 
      BEFORE INSERT ON "T_ADRESSES_SIG"              
      FOR EACH ROW 
      begin  
        if :new.ID_ADRESSES_SIG is null then
          select "SEQ_ADRESSES_SIG".nextval into :new.ID_ADRESSES_SIG from dual;
        end if;
      end;
    La ligne de v$session_wait ayant le même SID que le longops (format csv) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SID;SEQ#;EVENT;P1TEXT;P1;P1RAW;P2TEXT;P2;P2RAW;P3TEXT;P3;P3RAW;WAIT CLASS ID;WAIT CLASS#;WAIT CLASS;WAIT TIME;Seconds in Wait;STATE;WAIT TIME MICRO;TIME REMAINING MICRO;TIME SINCE LAST WAIT MICRO
    143;3866;SQL*Net message from client;driver id;1952673792;(RAW);#bytes;1;(RAW);;0;(RAW);2723168908;6;Idle;0;1267;WAITING;1266919508;-1;0
    Ne m'y connaissant pas plus que ça, je ne sais pas si ce SID correspond vraiment a celui que de ma procédure.
    Mais si vous voulez le contenu entier de v$session_wait et v$session_event je vous le poste.

  14. #14
    Expert éminent
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Par défaut
    tu n'utilises pas des tablespaces géré localement avec un stockage automatique ?

    Sinon, dans v$session_wait, l'attente doit changer régulièrement... ce serait pas mal de lancer un statpack sur 15 minutes pour voir un peu ce qui se passe.

  15. #15
    Membre averti
    Inscrit en
    Août 2008
    Messages
    19
    Détails du profil
    Informations personnelles :
    Âge : 52

    Informations forums :
    Inscription : Août 2008
    Messages : 19
    Par défaut
    Citation Envoyé par orafrance Voir le message
    tu n'utilises pas des tablespaces géré localement avec un stockage automatique ?
    Si, qu'est ce qui te fait penser le contraire ?
    Quelle requête dois je faire pour le vérifier ?

    Sinon j'en suis 1 945 000 lignes traitées et un temps restant estimé qui grimpe toujours pour atteindre 16.7 jours
    Le temps entre chaque commit de 5000 lignes est devenu tellement long que mon processus disparait de la vue V_$SESSION_LONGOPS entre chacun d'entre eux !

  16. #16
    Expert éminent
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Par défaut
    Citation Envoyé par Alien64 Voir le message
    Si, qu'est ce qui te fait penser le contraire ?
    t'as pas à mettre les clauses STORAGE en ASSM

Discussions similaires

  1. Update trés lent sur une grosse table
    Par neo.51 dans le forum Oracle
    Réponses: 21
    Dernier message: 14/12/2005, 11h06
  2. [Oracle] Mieux vaut une grosse table ou plein de petite ?
    Par ShinJava dans le forum PHP & Base de données
    Réponses: 16
    Dernier message: 30/11/2005, 16h32
  3. left join multiple sur grosses tables
    Par hn2k5 dans le forum Requêtes
    Réponses: 6
    Dernier message: 30/11/2005, 16h10
  4. Croisement d'une table avec elle même
    Par lelapin dans le forum Langage SQL
    Réponses: 2
    Dernier message: 28/09/2005, 07h44
  5. [Strategie]Pb recup données grosse table
    Par zach dans le forum JDBC
    Réponses: 32
    Dernier message: 28/01/2005, 15h08

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