Précédent   Forum des professionnels en informatique > Logiciels > Solutions d'entreprise > ERP > SAP
SAP Forum d'entraide sur SAP et sur la programmation avec le langage ABAP
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 25/06/2008, 15h55   #1
Invité régulier
 
Inscription : février 2004
Messages : 20
Détails du profil
Informations forums :
Inscription : février 2004
Messages : 20
Points : 7
Points : 7
Par défaut performance LOOP imbriqués

bonjour,

dans un programme abap j'ai 2 LOOP imbriqués :

- le premier parcourt une liste d'article (environ 3000)
- le deuxième parcourt une structure de 300000 lignes pour faire des sommes sur l'article en question

mon traitement fera donc au max 3000 * 300000 traitements.

y at-il une manière d'optimiser les LOOP pour réduire les temps de traitement (tri ou conditions particuliers...) ?

Code :
1
2
3
4
5
6
7
8

SORT wpt_article BY matnr.
SORT wpt_s920 BY matnr.
LOOP at wpt_article INTO wps_article.
               LOOP at wpt_s920 INTO wps_s920
                     where matnr = wps_article-matnr.
.............................
merci d'avance de l'aide fournie
cam360 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/06/2008, 16h08   #2
Membre expérimenté
 
Avatar de Celdrøn
 
Homme Celdrøn Valdersen
Consultant SAP
Inscription : juillet 2007
Messages : 438
Détails du profil
Informations personnelles :
Nom : Homme Celdrøn Valdersen
Âge : 26
Localisation : France

Informations professionnelles :
Activité : Consultant SAP

Informations forums :
Inscription : juillet 2007
Messages : 438
Points : 579
Points : 579
Envoyer un message via MSN à Celdrøn
Bonjour cam360,

Utilise les LOOP indéxés, c'est plus performant et ça t'evite de parcourir 3000fois la totalité de ta deuxième table.

Code :
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

SORT wpt_article BY matnr.
SORT wpt_s920 BY matnr.

LOOP AT wpt_article INTO wps_article.

CLEAR wps_s920.
READ TABLE wpt_s920
   WITH KEY matnr = wps_article-matnr
   BINARY SEARCH.

IF sy-subrc IS INITIAL.
   LOOP at wpt_s920 FROM sy-tabix INTO wps_s920.

        IF wps_s920-matnr > wps_article-matnr.
            EXIT.
        ENDIF.

*    Ton code.      

   ENDLOOP.
ENDIF.

ENDLOOP.
Impératif : la table sur laquelle on fait un READ TABLE.... avec un BINARY SEARCH doit être trié selon et dans l'ordre des clés de lecture.
Celdrøn est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/06/2008, 10h44   #3
Membre habitué
 
Inscription : juin 2003
Messages : 146
Détails du profil
Informations personnelles :
Âge : 31
Localisation : France, Vienne (Poitou Charente)

Informations forums :
Inscription : juin 2003
Messages : 146
Points : 135
Points : 135
Envoyer un message via MSN à Sh@m@n
bonjour,
je pense que ce qu'a mit celdron est tout à fait correcte, et je ne suis pas sur qu'il y ait de meilleur solution.
Sh@m@n est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/06/2008, 12h14   #4
Membre expérimenté
 
Avatar de Celdrøn
 
Homme Celdrøn Valdersen
Consultant SAP
Inscription : juillet 2007
Messages : 438
Détails du profil
Informations personnelles :
Nom : Homme Celdrøn Valdersen
Âge : 26
Localisation : France

Informations professionnelles :
Activité : Consultant SAP

Informations forums :
Inscription : juillet 2007
Messages : 438
Points : 579
Points : 579
Envoyer un message via MSN à Celdrøn
Salut,

En effet, je pense que cette solution est la meilleure bien qu'il existe un autre type de LOOP imbriqué indéxé (que j'ai vite laissé tomber) car il consiste a conserver l'index de la 2nd table (wpt_s920) et de repartir de cet index et faire des conditions pour vérifier si le n° article (en reprenant l'exemple) est le même etc., au lieu de faire un READ TABLE...

Un exemple pour rendre hommage à un vieux bout de code ^^.
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
DATA : w_wpt_s920_tabix TYPE sytabix.  "LIKE sy-tabix. (au choix)

SORT wpt_article BY matnr.
SORT wpt_s920 BY matnr.

w_wpt_s920_tabix = 1.

LOOP AT wpt_article INTO wps_article.

   LOOP at wpt_s920 FROM w_wpt_s920_tabix INTO wps_s920.

        IF wps_s920-matnr = wps_article-matnr.

 *              Ton code. 

        ELSEIF wps_s920-matnr > wps_article-matnr.
            w_wpt_s920_tabix = sy-tabix.
            EXIT.
        ENDIF.

   ENDLOOP.   "AT wpt_s920

ENDLOOP.   "AT wpt_article
Voilà, c'était à titre posthume

Au final, ça revient au même, si les deux tables sont triées selon la même clé mais c'est plus facile d'utiliser un READ TABLE.

A++.
Celdrøn est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/06/2008, 12h34   #5
Membre habitué
 
Inscription : juin 2003
Messages : 146
Détails du profil
Informations personnelles :
Âge : 31
Localisation : France, Vienne (Poitou Charente)

Informations forums :
Inscription : juin 2003
Messages : 146
Points : 135
Points : 135
Envoyer un message via MSN à Sh@m@n
et bien je dirai ke le BINARY SEARCH reste essentielle, car la recherche est plus rapide.

Sinon, j'aime bien ta seconde méthode Celdron, car elle permet de ne pas avoir de read table (qui va prendre du tps), alors que la conservation de l'index ne prends rien!!
Sh@m@n est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/06/2008, 14h08   #6
Membre expérimenté
 
Avatar de Celdrøn
 
Homme Celdrøn Valdersen
Consultant SAP
Inscription : juillet 2007
Messages : 438
Détails du profil
Informations personnelles :
Nom : Homme Celdrøn Valdersen
Âge : 26
Localisation : France

Informations professionnelles :
Activité : Consultant SAP

Informations forums :
Inscription : juillet 2007
Messages : 438
Points : 579
Points : 579
Envoyer un message via MSN à Celdrøn
Oui, le BINARY SEARCH reste forcement essentiel pour optimiser un READ TABLE, encore faut-il ne pas oublier de faire un SORT de sa table interne en fonction des clés de lecture, sinon ça marche pas ou alors c'est un gros coup d'bol (ou de cocu <= appeler sa copine dans la minute pour lui demander ce qu'elle fabrique ).

Sinon oui, la deuxième solution est moins consommatrice en temps, mais ça deviens vite une usine à gaz si la condition IF...ENDIF se complique. Et point de vue perf, ça doit se voir surtout sur un traitement de masse.

Bref cam360, t'as toutes les billes en main.

A++.
Celdrøn est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/06/2008, 15h41   #7
Invité régulier
 
Inscription : février 2004
Messages : 20
Détails du profil
Informations forums :
Inscription : février 2004
Messages : 20
Points : 7
Points : 7
Citation:
Envoyé par Celdrøn Voir le message
Salut,

En effet, je pense que cette solution est la meilleure bien qu'il existe un autre type de LOOP imbriqué indéxé (que j'ai vite laissé tomber) car il consiste a conserver l'index de la 2nd table (wpt_s920) et de repartir de cet index et faire des conditions pour vérifier si le n° article (en reprenant l'exemple) est le même etc., au lieu de faire un READ TABLE...

Un exemple pour rendre hommage à un vieux bout de code ^^.
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
DATA : w_wpt_s920_tabix TYPE sytabix.  "LIKE sy-tabix. (au choix)

SORT wpt_article BY matnr.
SORT wpt_s920 BY matnr.

w_wpt_s920_tabix = 1.

LOOP AT wpt_article INTO wps_article.

   LOOP at wpt_s920 FROM w_wpt_s920_tabix INTO wps_s920.

        IF wps_s920-matnr = wps_article-matnr.

 *              Ton code. 

        ELSEIF wps_s920-matnr > wps_article-matnr.
            w_wpt_s920_tabix = sy-tabix.
            EXIT.
        ENDIF.

   ENDLOOP.   "AT wpt_s920

ENDLOOP.   "AT wpt_article
Voilà, c'était à titre posthume

Au final, ça revient au même, si les deux tables sont triées selon la même clé mais c'est plus facile d'utiliser un READ TABLE.

A++.



Oui mais le EXIT me fait avancer d'un pas dans "wpt_s920" et pas dans "wpt_article"...
Imaginons que le 1er article de la table des articles n'existe pas dans wpt_s920, on va parcourir toute la table et ne retourner aucun résultat !
ce qui est faux puisque pour d'autres articles j'ai des valeurs dans "wpt_s920" !
cam360 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/06/2008, 16h40   #8
Membre expérimenté
 
Avatar de Celdrøn
 
Homme Celdrøn Valdersen
Consultant SAP
Inscription : juillet 2007
Messages : 438
Détails du profil
Informations personnelles :
Nom : Homme Celdrøn Valdersen
Âge : 26
Localisation : France

Informations professionnelles :
Activité : Consultant SAP

Informations forums :
Inscription : juillet 2007
Messages : 438
Points : 579
Points : 579
Envoyer un message via MSN à Celdrøn
A t'écouter, on croirait que le LOOP ne sert pas à incrémenter l'index à chaque nouvelle boucle... ^_^

Sinon, en effet, le EXIT va te faire sortir de la boucle sur wpt_s920, et si tu en sors, tu va reboucler sur wpt_article en te positionnant sur l'article suivant. Mais on ne va pas parcourir toute la table wpt_s920 puisqu'on test si les deux numéros d'article wps_s920-matnr et wps_article-matnr sont égaux. Si ce n'est le cas, ça veut dire que wps_s920-matnr est plus grand que wps_article-matnr,puisque tes deux tables sont triés par rapport au n° d'article(matnr) par ordre croissant et donc,de ce fait on va conserver l'index de wpt_s920 qui vaudra encore 1 donc à la prochaine boucle on repartira du début.

Si pour l'article suivant (wps_article-matnr), on retrouve une, ou plusieurs lignes (selon le contenu de ta 2nd table et l'algo à mettre en place), dès que wps_s920-matnr > wps_article-matnr, on va conserver l'index en cours (par exemple 3), et on repartira de l'index 3, sur la table wpt_s920, pour le wps_article-matnr d'après.

Je sais pas si j'ai été assez clair mais regarde bien ma condition IF...ELSEIF...ENDIF.

A+.
Celdrøn est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/06/2008, 16h51   #9
Invité régulier
 
Inscription : février 2004
Messages : 20
Détails du profil
Informations forums :
Inscription : février 2004
Messages : 20
Points : 7
Points : 7
désolé,
je me suis embrouillé tout seul avec les tabix...
en fait tout marche très bien comme ça et les temps de traitement ont été bien divisés !
je suis passé de 10min à 26s !!

j'ai essayé également de faire la différence entre le traitement avec le READ et le traitement sans, c'est quasi identique.

merci beaucoup
cam360 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/06/2008, 18h41   #10
Membre confirmé
 
Inscription : octobre 2007
Messages : 209
Détails du profil
Informations forums :
Inscription : octobre 2007
Messages : 209
Points : 211
Points : 211
pour moi le plus optimal est d'utiliser des read table from index dans des boucles do enddo sur les 2 tables

il suffit de gérer les 2 niveaux d'index et d'avancer en même temps (en ayant trié au préalable les 2 tables)

mais bon la solution est plus complexe à mettre en place et dans l'exemple il vaut mieux utiliser les loop indexés
splash1 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/08/2011, 10h59   #11
Invité de passage
 
Homme
Développeur ERP
Inscription : février 2011
Messages : 2
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 28
Localisation : France

Informations professionnelles :
Activité : Développeur ERP
Secteur : Industrie

Informations forums :
Inscription : février 2011
Messages : 2
Points : 4
Points : 4
Bonjour, je me permet d'ajouter un complément à cette discussion, même si le dernier message date de 2008.

Je viens de découvrir qu'on peut à la fois utiliser FROM sy-tabix et les conditions WHERE dans le LOOP. Cela évite d'avoir à refaire des test de sorties dans des conditions (IF blabla-champ1 <> trucmuche-champ1. EXIT. ENDIF.)

Voici un programme de test qui vous permet de voir le déroulement en debug:

Code ABAP :
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
REPORT  zzfwang.

TYPES: BEGIN OF ty_list,
  key TYPE char5,
  value TYPE char4,
END OF ty_list.

DATA: t_list TYPE TABLE OF ty_list.

DATA: s_list TYPE ty_list.

FIELD-SYMBOLS: <fs_list> TYPE ty_list.

MOVE: '00001' TO s_list-key,
      'VAL1'  TO s_list-value.
INSERT s_list INTO TABLE t_list.

MOVE: '00001' TO s_list-key,
      'VAL2'  TO s_list-value.
INSERT s_list INTO TABLE t_list.

MOVE: '00003' TO s_list-key,
      'DEB1'  TO s_list-value.
INSERT s_list INTO TABLE t_list.

MOVE: '00004' TO s_list-key,
      'DEB2'  TO s_list-value.
INSERT s_list INTO TABLE t_list.

MOVE: '00005' TO s_list-key,
      'DEB3'  TO s_list-value.
INSERT s_list INTO TABLE t_list.

MOVE: '00006' TO s_list-key,
      'FIN1'  TO s_list-value.
INSERT s_list INTO TABLE t_list.

SORT t_list BY key value.

READ TABLE t_list TRANSPORTING NO FIELDS
  WITH KEY key = '00003'
  BINARY SEARCH.

IF sy-subrc EQ 0.
  LOOP AT t_list FROM sy-tabix INTO s_list
  WHERE value+0(3) EQ 'DEB'.
    WRITE: s_list-key, ' ', s_list-value.
  ENDLOOP.
ENDIF.
FabienWang est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/08/2011, 13h51   #12
Membre expérimenté
 
Avatar de Celdrøn
 
Homme Celdrøn Valdersen
Consultant SAP
Inscription : juillet 2007
Messages : 438
Détails du profil
Informations personnelles :
Nom : Homme Celdrøn Valdersen
Âge : 26
Localisation : France

Informations professionnelles :
Activité : Consultant SAP

Informations forums :
Inscription : juillet 2007
Messages : 438
Points : 579
Points : 579
Envoyer un message via MSN à Celdrøn
Salut,

Ce qui me freine avec cette méthode c'est que j'ai peur que l'on parcourt toute la table à partir de l'indice donné.
__________________
Boaf...signature <= ça suffira ça ??
Celdrøn est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 18h18.


 
 
 
 
Partenaires

Hébergement Web