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 :

Procédure stockée dure trois jours pour se terminer


Sujet :

PL/SQL Oracle

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Développeur Java
    Inscrit en
    Février 2014
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Service public

    Informations forums :
    Inscription : Février 2014
    Messages : 5
    Points : 0
    Points
    0
    Par défaut Procédure stockée dure trois jours pour se terminer
    Bonjour à tous.
    Je suis débutant dans le PLSQL et j'ai pris dernièrement une base en production dans laquelle il existe quelques prcédures PLSQL. Un de ces procédure lorsque on l'execute prend trois jour pour s'achever puisque la table à qui se base compte plus de 40 millions d'enregistrement.
    Est ce quelqu'un dans ce forum peut optimiser son code.

    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
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
     
    create or replace
    PROCEDURE FACTURATION_POST_BG_FINAL(V_DATE_CALC VARCHAR2, V_DATE_DEB VARCHAR2, V_DATE_FIN VARCHAR2, V_ENTETE_FACT VARCHAR2) AS
    V_NLig number:=0;
    V_remise number:=0;
    V_prixTTC number;
    V_prixUHt number;
    V_TauxTVA number;
    V_prixUPublic number;
    V_PTVA  number;
    V_PUHT  number;
    V_LITR number;
    V_MR  number;
    V_totalHT number;
    V_totalTva number;
    V_quantite number;
    V_delais NUMBER;
    V_datedebuexo DATE;
    V_dateFINexo DATE;
    V_exo number;
    V_timbre  number:=0.400;
    V_NUM_FACT VARCHAR2(20);
    CURSOR SEL_OS IS 
    SELECT DISTINCT CLIENT.CODE_CLIENT,substr(bon.num_seri,7,6)as CODE_RUBR_BUDG,substr(bon.num_seri,1,6) as ancien_code,1
    FROM BON,CLIENT
    WHERE (BON.NUM_SERI  IN (SELECT NUM_SERI FROM BONDET_BGV where BONDET_BGV.DATE_BORD BETWEEN V_DATE_DEB AND V_DATE_FIN))
    AND (BON.NOM_PROCESSUS='CB')
    AND (CLIENT.ancien_code in (2,4,9))
    AND (BON.NUM_SERI NOT IN (SELECT BON_FACTURE_OS_PF.NUM_SERI FROM BON_FACTURE_OS_PF))
    UNION
    SELECT DISTINCT CLIENT.CODE_CLIENT,substr(bon.num_seri,7,6) as CODE_RUBR_BUDG,substr(bon.num_seri,1,6) as ancien_code,2
    FROM BON,CLIENT
    WHERE (BON.NUM_SERI  IN (SELECT NUM_SERI FROM BONDET_BGV where BONDET_BGV.DATE_BORD BETWEEN V_DATE_DEB AND V_DATE_FIN))
    AND (BON.NOM_PROCESSUS='CB')
    AND (CLIENT.ANCIEN_CODE =substr(bon.num_seri,1,6))
    AND (CLIENT.ancien_code not in (2,4,9))
    AND (BON.CODE_TYPE_BON IN (SELECT TYPE_BON.CODE_TYPE_BON FROM TYPE_BON
    WHERE TYPE_BON.CODE_NATU_CONS IN(SELECT NATURE_CONSOMMATION.CODE_NATU_CONS FROM NATURE_CONSOMMATION
    WHERE NATURE_CONSOMMATION.TYPE_FACT='POST')))
    AND (BON.NUM_SERI NOT IN (SELECT BON_FACTURE_OS_PF.NUM_SERI FROM BON_FACTURE_OS_PF))
    ORDER BY ANCIEN_CODE,CODE_RUBR_BUDG,1,2;
    ENR_OS SEL_OS%ROWTYPE;
    begin
      	 open SEL_OS;
      	 loop
    		Fetch SEL_OS  Into ENR_OS;
    		Exit When SEL_OS %notfound;
    		V_totalHT:=0;
    		V_totalTva:=0;
    		V_NUM_FACT := NUM_AUTO_FACTURE(V_ENTETE_FACT);
    		begin
    			SELECT CONDITION_COMMERCIALE.DELAIS_PAY, CONDITION_COMMERCIALE.EXOTIMB_FISC, CONDITION_COMMERCIALE.DATE_DEB_EXOTIMBRE,
    			CONDITION_COMMERCIALE.DATE_FIN_EXOTIMBRE into V_delais,   V_exo, V_datedebuexo,  V_dateFINexo
    			FROM CONDITION_COMMERCIALE
    		  	where (CONDITION_COMMERCIALE.CODE_CLIENT=ENR_OS.CODE_CLIENT)
    		  	and (CONDITION_COMMERCIALE.CODE_TYPE_CLIE IN ('4', '5','6'))
    		  	and (CONDITION_COMMERCIALE.NOM_PROCESSUS='CB');
    				EXCEPTION WHEN NO_DATA_FOUND THEN V_delais:=0; V_exo:=0; V_datedebuexo:=null;  V_dateFINexo:=null;
    		End;
    		V_timbre:=0;
    		if( V_exo=1)then
    	    	if(V_datedebuexo is not NULL  AND  V_dateFINexo is not  NULL )THEN
    			  if(V_datedebuexo>=TO_DATE(SYSDATE, 'DD/MM/RRRR')  AND  V_dateFINexo<=TO_DATE(SYSDATE, 'DD/MM/RRRR') )THEN
    		        SELECT TO_NUMBER(substr(val_param,3))/10  into V_timbre
    			    FROM PARAMETRE
    			    where PARAMETRE.CODE_PARAM='TIMB_FISC';
    	        end if;
    			if(V_datedebuexo is NULL )THEN
    				SELECT TO_NUMBER(substr(val_param,3))/10  into V_timbre
    			    FROM PARAMETRE
    			    where PARAMETRE.CODE_PARAM='TIMB_FISC';
    			end if;
    	     end if;
    	   end if;
    		insert into   FACTURE_OS_PF(FACTURE_OS_PF.NUM_FACT,FACTURE_OS_PF.CODE_RUBR_BUDG,FACTURE_OS_PF.ANNE_FACT, FACTURE_OS_PF.CODE_CLIENT,
    		FACTURE_OS_PF.MOIS_FACT,FACTURE_OS_PF.OBJET_FACT,FACTURE_OS_PF.DATE_FACT,FACTURE_OS_PF.DATE_CREA
    		 ,FACTURE_OS_PF.DATE_CAL_ECH,FACTURE_OS_PF.TIMB_FISC)
    		 values ( V_NUM_FACT,ENR_OS.CODE_RUBR_BUDG,TO_NUMBER(TO_CHAR(TO_DATE(V_DATE_CALC),'YYYY')),ENR_OS.CODE_CLIENT, TO_NUMBER(TO_CHAR(TO_DATE(V_DATE_CALC),'MM')),'facture post-facturée',TO_DATE(V_DATE_CALC, 'DD/MM/RRRR'),TO_DATE(SYSDATE, 'DD/MM/RRRR'),TO_DATE(V_DATE_CALC, 'DD/MM/RRRR')+V_delais,   V_timbre);
    		if(ENR_OS.ANCIEN_CODE<=9) then
        BEGIN
    			declare
    			CURSOR SEL_NB_BON is select DISTINCT BON.CODE_PROD,CARTE_BON.CODE_LITR
    			FROM BON,CARTE_BON
    			WHERE (BON.NUM_SERI  IN (SELECT NUM_SERI FROM BONDET_BGV where BONDET_BGV.DATE_BORD BETWEEN V_DATE_DEB AND V_DATE_FIN))
    			AND (BON.NOM_PROCESSUS='CB')
    			AND (BON.NUM_SERI=CARTE_BON.NUM_SERI)
    			AND (to_number(substr(bon.num_seri,1,6))=ENR_OS.ANCIEN_CODE)
          AND (substr(bon.num_seri,7,6) = ENR_OS.CODE_RUBR_BUDG) 
    			ORDER BY BON.CODE_PROD,CARTE_BON.CODE_LITR;
    			ENR_NB_BON SEL_NB_BON%ROWTYPE;
    			BEGIN
    			open SEL_NB_BON;
    			loop
    		  	    V_NLig:=V_NLig+1;
    				Fetch SEL_NB_BON  Into ENR_NB_BON;
    				Exit When SEL_NB_BON %notfound;
    				insert into  DETAIL_FACTURE_OS_PF (DETAIL_FACTURE_OS_PF.NUM_FACT,DETAIL_FACTURE_OS_PF.CODE_PROD,DETAIL_FACTURE_OS_PF.CODE_LITR,DETAIL_FACTURE_OS_PF.NUM_LIGN) values(V_NUM_FACT,ENR_NB_BON.CODE_PROD,ENR_NB_BON.CODE_LITR,V_NLig);
    				begin
    					declare
    					CURSOR SEL_BON is select DISTINCT BON.NUM_SERI
    					FROM BON,CARTE_BON
    													WHERE (BON.NUM_SERI  IN (SELECT NUM_SERI FROM BONDET_BGV where BONDET_BGV.DATE_BORD BETWEEN V_DATE_DEB AND V_DATE_FIN))
    													AND (BON.NOM_PROCESSUS='CB')
    													AND (BON.NUM_SERI=CARTE_BON.NUM_SERI)
    													AND (BON.CODE_PROD=ENR_NB_BON.CODE_PROD)
    													AND (CARTE_BON.CODE_LITR=ENR_NB_BON.CODE_LITR)
    													AND (to_number(substr(bon.num_seri,1,6))=ENR_OS.ANCIEN_CODE)
                              AND (substr(bon.num_seri,7,6) = ENR_OS.CODE_RUBR_BUDG) 
    													AND (BON.NUM_SERI NOT IN (SELECT BON_FACTURE_OS_PF.NUM_SERI FROM BON_FACTURE_OS_PF));
    													ENR_BON SEL_BON%ROWTYPE;
    					BEGIN
    						 open SEL_BON;
    						 V_quantite :=0;
    						 V_prixTTC:=0;
    						loop
    							Fetch SEL_BON  Into ENR_BON;
    							Exit When SEL_BON %notfound;
    							begin
    								select 	STRUCTURE_PRIX_PRD.MARGE_REVEND ,STRUCTURE_PRIX_PRD.PRIX_TVA ,STRUCTURE_PRIX_PRD.PRIX_UNIT_HT
    								INTO V_MR  , V_PTVA  , V_PUHT
    								from STRUCTURE_PRIX_PRD
    								where
    								STRUCTURE_PRIX_PRD.CODE_PROD=ENR_NB_BON.CODE_PROD
    								and V_DATE_CALC BETWEEN  STRUCTURE_PRIX_PRD.DATE_DEB AND 	STRUCTURE_PRIX_PRD.DATE_FIN;
    							end;
    							begin
    								SELECT LITRAGE.QUAN_LITR INTO V_LITR FROM LITRAGE WHERE LITRAGE.CODE_LITR=ENR_NB_BON.CODE_LITR;
                    select remise into V_remise from remise where code_client = ENR_OS.CODE_CLIENT and code_prd = ENR_NB_BON.CODE_PROD;
                    EXCEPTION WHEN NO_DATA_FOUND THEN V_remise:=0;
                  end;
                 	V_quantite:=V_quantite +1;
    							V_prixTTC := V_prixTTC +( V_LITR * ((V_MR+V_PTVA+V_PUHT)/1000));
    							V_prixUHt :=  V_LITR * ((V_MR+V_PUHT)/1000);
    							V_prixUPublic := (V_MR+V_PTVA+V_PUHT)/1000;
    							V_totalHT:=V_totalHT+( V_LITR * ((V_MR+V_PUHT)/1000));
    							 V_totalTva:=V_totalTva +( V_LITR*(V_PTVA/1000));
    							 insert into  BON_FACTURE_OS_PF(BON_FACTURE_OS_PF.NUM_FACT,BON_FACTURE_OS_PF.NUM_LIGN,BON_FACTURE_OS_PF.NUM_SERI)
    							 values(V_NUM_FACT,V_NLig,ENR_BON.NUM_SERI);
    						end loop;
    						close SEL_BON;
    					END;
    				end;
            update DETAIL_FACTURE_OS_PF set DETAIL_FACTURE_OS_PF.PRIX_UNIT_HT=V_prixUHt ,
    				DETAIL_FACTURE_OS_PF.PRIX_TOTA_TTC=V_prixTTC,
    				DETAIL_FACTURE_OS_PF.PRIX_UNIT_PUB=V_prixUPublic,
    				DETAIL_FACTURE_OS_PF.PRIX_TVA =  V_PTVA/1000 ,
    				DETAIL_FACTURE_OS_PF.QUANTITE= V_quantite * V_LITR,
    				DETAIL_FACTURE_OS_PF.NBR_BONS= V_quantite,
            detail_facture_os_pf.taux_tva = V_remise
    				where (DETAIL_FACTURE_OS_PF.NUM_FACT=V_NUM_FACT)
    				 and( DETAIL_FACTURE_OS_PF.NUM_LIGN=V_NLig);
    			end loop;
    			close SEL_NB_BON;
    			END;
    		end;
        end if;
    		if(ENR_OS.ANCIEN_CODE > 9) then
        BEGIN
    			declare
    			CURSOR SEL_NB_BON is select DISTINCT BON.CODE_PROD,CARTE_BON.CODE_LITR
    			FROM BON,CARTE_BON
    			WHERE (BON.NUM_SERI  IN (SELECT NUM_SERI FROM BONDET_BGV where BONDET_BGV.DATE_BORD BETWEEN V_DATE_DEB AND V_DATE_FIN))
    			AND (BON.NOM_PROCESSUS='CB')
    			AND (BON.NUM_SERI=CARTE_BON.NUM_SERI)
    			AND (to_number(substr(bon.num_seri,1,6))=ENR_OS.ANCIEN_CODE)
          AND (substr(bon.num_seri,7,6) = ENR_OS.CODE_RUBR_BUDG) 
    			AND (BON.CODE_TYPE_BON IN (SELECT TYPE_BON.CODE_TYPE_BON FROM TYPE_BON
    			WHERE TYPE_BON.CODE_NATU_CONS IN(SELECT NATURE_CONSOMMATION.CODE_NATU_CONS FROM NATURE_CONSOMMATION
    			WHERE NATURE_CONSOMMATION.TYPE_FACT='POST')))
    			AND (BON.NUM_SERI NOT IN (SELECT BON_FACTURE_OS_PF.NUM_SERI FROM BON_FACTURE_OS_PF))
    			ORDER BY BON.CODE_PROD,CARTE_BON.CODE_LITR;
    			ENR_NB_BON SEL_NB_BON%ROWTYPE;
    			BEGIN
    			open SEL_NB_BON;
    			loop
    		  	    V_NLig:=V_NLig+1;
    				Fetch SEL_NB_BON  Into ENR_NB_BON;
    				Exit When SEL_NB_BON %notfound;
    				insert into  DETAIL_FACTURE_OS_PF (DETAIL_FACTURE_OS_PF.NUM_FACT,DETAIL_FACTURE_OS_PF.CODE_PROD,DETAIL_FACTURE_OS_PF.CODE_LITR,DETAIL_FACTURE_OS_PF.NUM_LIGN) values(V_NUM_FACT,ENR_NB_BON.CODE_PROD,ENR_NB_BON.CODE_LITR,V_NLig);
    				begin
    					declare
    					CURSOR SEL_BON is select DISTINCT BON.NUM_SERI
    					FROM BON,CARTE_BON
    													WHERE (BON.NUM_SERI  IN (SELECT NUM_SERI FROM BONDET_BGV where BONDET_BGV.DATE_BORD BETWEEN V_DATE_DEB AND V_DATE_FIN))
    													AND (BON.NOM_PROCESSUS='CB')
    													AND (BON.NUM_SERI=CARTE_BON.NUM_SERI)
    													AND (BON.CODE_PROD=ENR_NB_BON.CODE_PROD)
    													AND (CARTE_BON.CODE_LITR=ENR_NB_BON.CODE_LITR)
    													AND (to_number(substr(bon.num_seri,1,6))=ENR_OS.ANCIEN_CODE)
                              AND (substr(bon.num_seri,7,6) = ENR_OS.CODE_RUBR_BUDG) 
                              AND (BON.CODE_TYPE_BON IN (SELECT TYPE_BON.CODE_TYPE_BON FROM TYPE_BON
    													WHERE TYPE_BON.CODE_NATU_CONS IN(SELECT NATURE_CONSOMMATION.CODE_NATU_CONS FROM NATURE_CONSOMMATION
    													WHERE NATURE_CONSOMMATION.TYPE_FACT='POST')))
    													AND (BON.NUM_SERI NOT IN (SELECT BON_FACTURE_OS_PF.NUM_SERI FROM BON_FACTURE_OS_PF));
    													ENR_BON SEL_BON%ROWTYPE;
    					BEGIN
    						 open SEL_BON;
    						 V_quantite :=0;
    						 V_prixTTC:=0;
    						loop
    							Fetch SEL_BON  Into ENR_BON;
    							Exit When SEL_BON %notfound;
    							begin
    								select 	STRUCTURE_PRIX_PRD.MARGE_REVEND ,STRUCTURE_PRIX_PRD.PRIX_TVA ,STRUCTURE_PRIX_PRD.PRIX_UNIT_HT
    								INTO V_MR  , V_PTVA  , V_PUHT
    								from STRUCTURE_PRIX_PRD
    								where
    								STRUCTURE_PRIX_PRD.CODE_PROD=ENR_NB_BON.CODE_PROD
    								and V_DATE_CALC BETWEEN  STRUCTURE_PRIX_PRD.DATE_DEB AND 	STRUCTURE_PRIX_PRD.DATE_FIN;
    							end;
    							begin
    								SELECT LITRAGE.QUAN_LITR INTO V_LITR FROM LITRAGE WHERE LITRAGE.CODE_LITR=ENR_NB_BON.CODE_LITR;
                    select remise into V_remise from remise where code_client = ENR_OS.CODE_CLIENT and code_prd = ENR_NB_BON.CODE_PROD;
                    EXCEPTION WHEN NO_DATA_FOUND THEN V_remise:=0;
                  end;
                 	V_quantite:=V_quantite +1;
    							V_prixTTC := V_prixTTC +( V_LITR * ((V_MR+V_PTVA+V_PUHT)/1000));
    							V_prixUHt :=  V_LITR * ((V_MR+V_PUHT)/1000);
    							V_prixUPublic := (V_MR+V_PTVA+V_PUHT)/1000;
    							V_totalHT:=V_totalHT+( V_LITR * ((V_MR+V_PUHT)/1000));
    							 V_totalTva:=V_totalTva +( V_LITR*(V_PTVA/1000));
    							 insert into  BON_FACTURE_OS_PF(BON_FACTURE_OS_PF.NUM_FACT,BON_FACTURE_OS_PF.NUM_LIGN,BON_FACTURE_OS_PF.NUM_SERI)
    							 values(V_NUM_FACT,V_NLig,ENR_BON.NUM_SERI);
    						end loop;
    						close SEL_BON;
    					END;
    				end;
            update DETAIL_FACTURE_OS_PF set DETAIL_FACTURE_OS_PF.PRIX_UNIT_HT=V_prixUHt ,
    				DETAIL_FACTURE_OS_PF.PRIX_TOTA_TTC=V_prixTTC,
    				DETAIL_FACTURE_OS_PF.PRIX_UNIT_PUB=V_prixUPublic,
    				DETAIL_FACTURE_OS_PF.PRIX_TVA =  V_PTVA/1000 ,
    				DETAIL_FACTURE_OS_PF.QUANTITE= V_quantite * V_LITR,
    				DETAIL_FACTURE_OS_PF.NBR_BONS= V_quantite,
            detail_facture_os_pf.taux_tva = V_remise
    				where (DETAIL_FACTURE_OS_PF.NUM_FACT=V_NUM_FACT)
    				 and( DETAIL_FACTURE_OS_PF.NUM_LIGN=V_NLig);
    			end loop;
    			close SEL_NB_BON;
    			END;
    		end;
        end if; 
        update FACTURE_OS_PF set FACTURE_OS_PF.MONT_HT=	V_totalHT,
    		FACTURE_OS_PF.MONT_TVA= V_totalTva,
    		FACTURE_OS_PF.MONT_TTC= V_totalHT+V_totalTva
    		where
    		FACTURE_OS_PF.NUM_FACT=V_NUM_FACT;
    			begin
    				declare
    				CURSOR SEL_LIV is SELECT DISTINCT LIVRAISON.NUM_BL from
    				 LIVRAISON, BON,BON_FACTURE_OS_PF,FACTURE_OS_PF
    				where (LIVRAISON.NUM_OS=BON.NUM_OS)
    				and (BON.NUM_SERI = BON_FACTURE_OS_PF.NUM_SERI)
    				and (BON_FACTURE_OS_PF.NUM_FACT=FACTURE_OS_PF.NUM_FACT)
    				and (FACTURE_OS_PF.NUM_FACT=V_NUM_FACT)
    				;
    				LIVFAC SEL_LIV%ROWTYPE;
    				BEGIN
    					open SEL_LIV;
    					loop
    						Fetch SEL_LIV  Into LIVFAC	;
    						Exit When SEL_LIV %notfound;
    						insert into FACT_OSPF_LIVRAISON(FACT_OSPF_LIVRAISON.NUM_BL,FACT_OSPF_LIVRAISON.NUM_FACT)values(LIVFAC.NUM_BL,V_NUM_FACT);
    					END LOOP;
    					CLOSE SEL_LIV;
    				end;
    			end;
    		end loop;
    		close SEL_OS;
    	commit;
    	/*MAJ_ETAT_DET_OS_PF ;
    	MAJ_ETAT_OS_PF;*/
    end;
    Merci d'avance

  2. #2
    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
    Ce type d’algorithme qui traite ligne par ligne est une Berezina en présence de la volumétrie importante des données. Le premier réflexe este de travailler par lot en employant les collections et l’instruction FOR ALL. Il faut analyser aussi les requêtes SQL parce que la présence du distinct et l’order by ne sont pas de bonnes signés. Et il faut bien comprendre ce que la procédure fait.
    En conséquence pour une première approche les pistes sont :
    • Trace du traitement pour avoir une idée de ce qui se passe
    • Remonter les jointures du code dans le curseur principal
    • Employer les collections
    • Employer un algorithme ensembliste de type Insert Into Table select … From … à la place de Open cursor ; Insert into table ; Close cursor

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Développeur Java
    Inscrit en
    Février 2014
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Service public

    Informations forums :
    Inscription : Février 2014
    Messages : 5
    Points : 0
    Points
    0
    Par défaut
    Citation Envoyé par mnitu Voir le message
    Ce type d’algorithme qui traite ligne par ligne est une Berezina en présence de la volumétrie importante des données. Le premier réflexe este de travailler par lot en employant les collections et l’instruction FOR ALL. Il faut analyser aussi les requêtes SQL parce que la présence du distinct et l’order by ne sont pas de bonnes signés. Et il faut bien comprendre ce que la procédure fait.
    En conséquence pour une première approche les pistes sont :
    • Trace du traitement pour avoir une idée de ce qui se passe
    • Remonter les jointures du code dans le curseur principal
    • Employer les collections
    • Employer un algorithme ensembliste de type Insert Into Table select … From … à la place de Open cursor ; Insert into table ; Close cursor
    Bonjour,
    Merci pour votre réponse
    concernant le distinct et le order by c'est une obligation pour les employer puisque il ya pas de jointure entre les deux tables
    mais votre remarque de travail avec le Create table au lieu curseur peut être utile
    Merci

  4. #4
    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
    Je me demande bien ce que vous auriez pu comprendre de ma réponse !

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    développeur Oracle
    Inscrit en
    Février 2014
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Roumanie

    Informations professionnelles :
    Activité : développeur Oracle
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Février 2014
    Messages : 27
    Points : 26
    Points
    26
    Par défaut
    Salut oracle1920,

    Tu as une tâche difficile, mais je crois que tu peux atténues considérablement la durée d'exécution.

    Il y a quelques aspects je veux presente:

    1. Ton code n'est pas lisible, tu dois utiliser un outil comme BEAUTIFIER de PL/SQL (ou une autre comme ça).

    2. Le code n'a pas tous l'EXCEPTION bloc (on traite seulement l'exception NO_DATA_FOUND mais autres exceptions comme
    • TOO_MANY_ERRORS
    • internal error code
    • maximum open cursors exceeded


    peux être rencontrées).

    3. Enregistrement opérations (avec log fonctions et table)

    4. TRES IMPORTANT Tu as un curseur grande SEL_OS et deux curseurs à l'intérieur (SEL_NB_BON et SEL_BON) et ils nécessitent beaucoup de ressources.
    Un meilleur approche est d'utiliser des opérations comme
    SELECT ...
    BULK COLLECT INTO l_array
    FROM ...
    ou l_array sont Oracle collections. La vitesse d'exécution est grandement améliorée.

    5. TRES IMPORTANT Tu as seulement un COMMIT pour très longues opérations et probablement milliers de INSERT/UPDATE opérations. Tu dois faire un mécanisme afin que après
    chaque 5000 - 1000 INSERT/UPDATE opérations le COMMIT opération devrait être lancée.

    6. TRES IMPORTANT Vérifiez que tu as indices bons sur les tables impliquées sur SELECT/INSERT/UPDATE opérations.
    Probablement tu peux utiliser :
    indices B-TREE(faible cardinalité) par exemple sur colonnes
    • BON.NUM_SERI
    • BONDET_BGV.DATE_BORD


    :indices BITMAP (cardinalité élevée) par exemple sur colonnes
    • CLIENT.ANCIEN_CODE
    • BON.NOM_PROCESSUS
    • NATURE_CONSOMMATION.TYPE_FACT
    • CONDITION_COMMERCIALE.CODE_TYPE_CLIE
    • CONDITION_COMMERCIALE.NOM_PROCESSUS
    • PARAMETRE.CODE_PARAM



    un autre très bon aider peux être les partitions.

    7. TRES IMPORTANT Cette type de code peut utiliser très bien la parallélisation (avec paquet dbms_parallel_execute ou fonctions PARALLEL_ENABLE).
    J'ai utilisé cette solution et un code qu'ai duré 15 heures a été diminue à deux heures.

    8. pour un meilleur visualisation de code tu peux transformer une part du code en procédures stockées.

    Succès!

  6. #6
    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
    Citation Envoyé par danvoiculet Voir le message

    Il y a quelques aspects je veux presente: ...
    C’est dure à faire part entre ce qui est totalement erroné et ce qui ajoute à l’optimisation autant que la pointure du programmeur.

Discussions similaires

  1. Réponses: 1
    Dernier message: 06/05/2013, 14h35
  2. Réponses: 0
    Dernier message: 17/09/2008, 09h53
  3. [MySQL5] Procédures Stockées de Mise à jour
    Par Shinn77 dans le forum SQL Procédural
    Réponses: 4
    Dernier message: 26/10/2007, 14h17
  4. Réponses: 2
    Dernier message: 20/09/2006, 14h38
  5. Réponses: 3
    Dernier message: 09/09/2004, 11h31

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