Grundsätzlich hat a-d-t ja recht - aber ganz so kategorisch würde ich die Version mit den Workareas trotzdem nicht ablehnen.a-dead-trousers hat geschrieben:Ach ja: Auf keinen Fall LOOP AT ... INTO ... verwenden. Schon gar nicht bei so großen Monster-Tabellen. IMMER mit Feldsymbolen (ASSIGNING) oder Zeigern (REFERENCE INTO) arbeiten.
Code: Alles auswählen.
CLEAR ls_prps.
LOOP AT lt_prps_auth INTO ls_prps_auth WHERE display IS NOT INITIAL.
READ TABLE lt_prps INTO ls_prps
WITH KEY objnr = ls_prps_auth-objnr.
IF sy-subrc <> 0.
CONTINUE.
ENDIF.
lsr_objnr-low = ls_prps-objnr.
APPEND lsr_objnr TO er_objnr.
CLEAR: ls_pspnr_info.
MOVE-CORRESPONDING ls_prps TO ls_pspnr_info.
INSERT ls_pspnr_info INTO TABLE et_pspnr_info.
ls_prctr_info-prctr = ls_prps-prctr.
ls_prctr_info-kokrs = ls_prps-pkokr.
COLLECT ls_prctr_info INTO et_prctr_info.
ENDLOOP.
Code: Alles auswählen.
Treffer Brutto [µsec] Netto [µsec] Brutto [%] Netto [%]
1 198.025.221 189.441.558 94.25 90.17
Viel Text, aber keine Infos. Nicht einmal die "Methode" nennst Du beim Namen.Damit ich eine Laufzeitanalyse machen kann habe ich den Report mit geringeren Datensätzen laufen lassen.
Und am meisten Zeit hat die Methode mit diesem Loop gebraucht.
Ich kann die Datei nicht hochladen.
Ich stell den betreffenden Auszug hier rein.
Warum laedst Du Daten in eine interne Tabelle, die Du in dem Loop ueberhaupt nicht benoetigst?LOOP AT lt_prps_auth INTO ls_prps_auth WHERE display IS NOT INITIAL.
Sind die beiden Tabelle lt_prps_auth und lt_prps beide sehr groß? Wenn ja wird dein Laufzeitproblem mindestens durch die oben angegebenen Programmzeilen verursacht werden. ( 200.000 x 200.000 = 40.000.000.000 )c oco hat geschrieben:Code: Alles auswählen.
... LOOP AT lt_prps_auth INTO ls_prps_auth WHERE display IS NOT INITIAL. READ TABLE lt_prps INTO ls_prps WITH KEY objnr = ls_prps_auth-objnr. ... ENDLOOP.
Garantiert hast Du recht, und nahezu die komplette Laufzeit in der Loop geht fürblack_adept hat geschrieben:c oco hat geschrieben: Sind die beiden Tabelle lt_prps_auth und lt_prps beide sehr groß? Wenn ja wird dein Laufzeitproblem mindestens durch die oben angegebenen Programmzeilen verursacht werden. ( 200.000 x 200.000 = 40.000.000.000 )
und könnte dadurch gelöst werden, dass beide Tabellen mit einem sinnvollen Schlüssel definiert werden und mit diesem auch auf sie zugegriffen wird.
Code: Alles auswählen.
READ TABLE lt_prps INTO ls_prps
WITH KEY objnr = ls_prps_auth-objnr.
Nur als Anmerkung: der READ TABLE ... WITH KEY macht nicht notwendigerweise eine sequentielle Suche. Ist in dem Beispiel LT_PRPS eine SORTED oder HASHED TABLE mit dem Schlüssel OBJNR wird dieser Schlüssel auch verwendet, d.h. es findet eine binäre Suche bzw. ein direkter Schlüsselzugriff statt.Frank Dittrich hat geschrieben:Garantiert hast Du recht, und nahezu die komplette Laufzeit in der Loop geht fürblack_adept hat geschrieben:c oco hat geschrieben: Sind die beiden Tabelle lt_prps_auth und lt_prps beide sehr groß? Wenn ja wird dein Laufzeitproblem mindestens durch die oben angegebenen Programmzeilen verursacht werden. ( 200.000 x 200.000 = 40.000.000.000 )
und könnte dadurch gelöst werden, dass beide Tabellen mit einem sinnvollen Schlüssel definiert werden und mit diesem auch auf sie zugegriffen wird.drauf.Code: Alles auswählen.
READ TABLE lt_prps INTO ls_prps WITH KEY objnr = ls_prps_auth-objnr.
Wenn man bei Tabelle lt_prps die sequentielle Suche vermeidet (je nach sonstiger Verwendung der itab und SAP-Release unterschiedliche Möglichkeiten (SORTED oder HASHED TABLE mit passendem Key, oder einfach auch die STANDARD TABLE vor der LOOP einmal passend sortieren und dann mit BINARY SEARCH drauf zugreifen oder mal die Tipps&Tricks-Section der SE30 nach der performanten Verarbeitung interner Tabellen in verschachtelten LOOPs durchsuchen) wird diese LOOP deutlich schneller.
Zu groß nicht. Der Kernel macht aber "5-er Häppchen" daraus, d.h. es finden int(lines(range)/5)+1 Zugriffe auf die DB statt. Macht die Abfrage aber auch nicht schneller...Frank Dittrich hat geschrieben: Das hilft aber nichts, wenn das Ziel dann eine Range mit ca. 100000 EInträgen ist.
Für SELECTs mit WHERE field IN range ... kann man das vergessen, weil das SELECT-Statement zu groß wird.
ACK.Frank Dittrich hat geschrieben: Und wenn man die Range in LOOP AT itab WHERE field IN range ... verwendet und itab auch wieder ca. 200000 EInträge hat, hat man das jetzige Poblem nur an eine andere Stelle verschoben.
Sehe ich auch so.Frank Dittrich hat geschrieben: Die Frage ist also, was soll eigentlich erreicht werden, wie sieht das Mengengerüst für die zu analysierenden Tabellen aus, welche Menge Daten muss am Ende selektiert werden, usw...
Frank
[/quote]Unit605 hat geschrieben: Mein erster Blick viel sofort auf:
Warum laedst Du Daten in eine interne Tabelle, die Du in dem Loop ueberhaupt nicht benoetigst?LOOP AT lt_prps_auth INTO ls_prps_auth WHERE display IS NOT INITIAL.
Alle Datensaetze wo das Feld Display nicht initial sind, gehoeren erst gar nicht in die Tabelle.
ja sie sind beide gleich groß.black_adept hat geschrieben:Sind die beiden Tabelle lt_prps_auth und lt_prps beide sehr groß? Wenn ja wird dein Laufzeitproblem mindestens durch die oben angegebenen Programmzeilen verursacht werden. ( 200.000 x 200.000 = 40.000.000.000 )c oco hat geschrieben:Code: Alles auswählen.
... LOOP AT lt_prps_auth INTO ls_prps_auth WHERE display IS NOT INITIAL. READ TABLE lt_prps INTO ls_prps WITH KEY objnr = ls_prps_auth-objnr. ... ENDLOOP.
und könnte dadurch gelöst werden, dass beide Tabellen mit einem sinnvollen Schlüssel definiert werden und mit diesem auch auf sie zugegriffen wird.
In der Tabelle lt_prps sind alle PSP-Elemente drin.Frank Dittrich hat geschrieben: Die Frage ist also, was soll eigentlich erreicht werden, wie sieht das Mengengerüst für die zu analysierenden Tabellen aus, welche Menge Daten muss am Ende selektiert werden, usw...
Frank
Code: Alles auswählen.
ls_pspnr_info-posid = ls_prps-posid.
ls_pspnr_info-pspnr = ls_prps-pspnr.
ls_pspnr_info-objnr = ls_prps-objnr.
ls_pspnr_info-prctr = ls_prps-prctr.
ls_pspnr_info-post1 = ls_prps-post1.
ls_pspnr_info-psphi = ls_prps-psphi.
ls_pspnr_info-pkokr = ls_prps-pkokr.
ls_pspnr_info-izwek = ls_prps-izwek.
Code: Alles auswählen.
ls_prctr_info-prctr = ls_prps-prctr.
ls_prctr_info-kokrs = ls_prps-pkokr.
[/quote]Haubi hat geschrieben: Nur als Anmerkung: der READ TABLE ... WITH KEY macht nicht notwendigerweise eine sequentielle Suche. Ist in dem Beispiel LT_PRPS eine SORTED oder HASHED TABLE mit dem Schlüssel OBJNR wird dieser Schlüssel auch verwendet, d.h. es findet eine binäre Suche bzw. ein direkter Schlüsselzugriff statt.
Code: Alles auswählen.
DATA: lt_prps TYPE STANDARD TABLE OF prps. --> Soll ich es vom Typ Hash Table machen obwohl ich unten mit Binary Search suche??
DELETE lt_prps_auth WHERE display IS NOT INITIAL. --> alles was Berechtigung hat fliegt raus
LOOP AT lt_prps_auth ASSIGNING <ls_prps_auth>.
READ TABLE lt_prps TRANSPORTING NO FIELDS WITH KEY objnr = <ls_prps_auth>-objnr BINARY SEARCH.
IF sy-subrc = 0. --> aus der Tabelle sollen alle Objekte rausfliegen, die keine Berechtigung haben
DELETE lt_prps INDEX sy-tabix.
ENDIF.
ENDLOOP.
IF lt_prps IS NOT INITIAL.
MOVE-CORRESPONDING lt_prps to lt_pspnr_info.
IF sy-subrc = 0.
SELECT objnr AS low --> hier bin ich mir unsicher, ob das was bringt
INTO CORRESPONDING FIELDS OF TABLE er_objnr
FROM prps
FOR ALL ENTRIES IN lt_prps
WHERE objnr = lt_prps-objnr.
ls_objnr-sign = 'I'.
ls_objnr-option = 'EQ'.
MODIFY er_objnr FROM ls_objnr
TRANSPORTING sign option
WHERE sign NE 'I'.
ENDIF.
Code: Alles auswählen.
ls_prctr_info-prctr = ls_prps-prctr.
ls_prctr_info-kokrs = ls_prps-pkokr.
COLLECT ls_prctr_info INTO et_prctr_info.
Code: Alles auswählen.
DATA: lt_prps TYPE STANDARD TABLE OF prps. --> Soll ich es vom Typ Hash TABLE machen obwohl ich unten mit BINARY SEARCH suche??
DELETE lt_prps_auth WHERE display IS NOT INITIAL. --> alles was Berechtigung hat fliegt raus
LOOP AT lt_prps_auth ASSIGNING <ls_prps_auth>.
READ TABLE lt_prps TRANSPORTING NO FIELDS WITH KEY objnr = <ls_prps_auth>-objnr BINARY SEARCH.