Performance

Getting started ... Alles für einen gelungenen Start.
4 Beiträge • Seite 1 von 1
4 Beiträge Seite 1 von 1

Performance

Beitrag von schick (ForumUser / 52 / 5 / 15 ) »
Hallo zusammen,

ich bin zur Zeit dabei Anpassungen an einem etwas älteren Programm durchzuführen.
Das ganze ist nicht sonderlich elegant programmiert und hinsichtlich Performanceaspekten sicherlich optimierbar.

An einer Stelle bin ich mir unsicher, was die bessere Vorgehensweise ist.
Um nicht das komplette Programm mit allem drum und dran kopieren zu müssen, versuche ich mal das Problem vereinfacht darzustellen:

Das bestehende Coding sieht in etwa so aus:

Code: Alles auswählen.

SELECT * 
FROM vbak 
INTO TABLE lt_vbak.

LOOP AT lt_vbak INTO ls_vbak.

SELECT FROM vbap INTO TABLE lt_vbap WHERE vbeln EQ ls_vbak-vbeln.

...

CALL FUNCTION 'X'
EXPORTING
TABLES 
position = lt_vbap
EXCEPTIONS.

...

ENDLOOP.
Zunächst hatte ich gedacht, ich mache das ganze wie folgt:

Code: Alles auswählen.

SELECT * 
FROM vbak 
INTO TABLE lt_vbak.

SELECT *
FROM vbap
INTO TABLE lt_vbap
FOR ALL ENTRIES IN lt_vbak.

LOOP AT lt_vbak INTO ls_vbak.

...

CALL FUNCTION 'X'
EXPORTING
TABLES 
position = lt_vbap
EXCEPTIONS.

...

ENDLOOP.
So funktioniert allerdings der Aufruf des Funktionsbausteins nicht, bzw. liefert falsche Ergebnisse.
Ich möchte allerdings trotzdem eigentlich ungern einen SELECT im LOOP machen, daher suche ich nach eleganteren Möglichkeiten!

Spontan kommt mir sowas als Option in den Sinn, ich bin mir aber nicht sicher, ob das wirklich performanter ist... (sonderlich "elegant" ist es ohnehin nicht):

Code: Alles auswählen.

SELECT * 
FROM vbak 
INTO TABLE lt_vbak.

SELECT *
FROM vbap
INTO TABLE lt_vbap
FOR ALL ENTRIES IN lt_vbak.

LOOP AT lt_vbak INTO ls_vbak.

lt_vbap_neu = lt_vbap.
DELETE lt_vbap_neu WHERE vbeln NE lt_vbak-vbeln.

...

CALL FUNCTION 'X'
EXPORTING
TABLES 
position = lt_vbap_neu
EXCEPTIONS.

...

ENDLOOP.
Ich freue mich über Anregungen! :-)


Randbemerkung:
Sowohl "SELECT *" als auch die "tollen" Bezeichner ala "lt_vbak" sind nur hier als Platzhalter, im richtigen Programm ist das anders gelöst...

Edit:
Releasestand ist übrigens 7.4

gesponsert
Stellenangebote auf ABAPforum.com schalten
kostenfrei für Ausbildungsberufe und Werksstudenten


Re: Performance

Beitrag von lausek (ForumUser / 64 / 2 / 20 ) »
Also ich weiß nicht, wie viele Einträge insgesamt rausgelesen werden, aber deine Variante im Loop sieht wirklich nicht ganz so gut aus. Das liegt aber hauptsächlich daran, dass du in jedem Durchlauf eine Tabelle kopierst und dann mit DELETE nochmal über die (wahrscheinlich) unsortierte Kopie drüber musst.

Das vereinfachte Problem, das du schilderst, sieht für mich sehr nach JOIN aus. Geht es denn damit nicht in einem Select? Man sollte hier beachten, dass der Transport überflüssiger Daten von DB nach Applikationsserver die Performance auch nach oben treiben kann.

Außerdem könntest du dir mal LOOP AT ... GROUP BY anschauen. Das ist auch eine neuere Funktion für Schleifen und gibt dir die Möglichkeit, die große, äußere Tabelle in kleinen Gruppen zu durchlaufen.

Kleine Anmerkung noch: es ist immer ratsam eine IF ... IS NOT INITIAL-Abfrage um Selects mit FOR ALL ENTRIES zu machen, da bei leerer Tabelle einfach alles geladen wird. Nicht gut ^^

Re: Performance

Beitrag von schick (ForumUser / 52 / 5 / 15 ) »
lausek hat geschrieben:Also ich weiß nicht, wie viele Einträge insgesamt rausgelesen werden, aber deine Variante im Loop sieht wirklich nicht ganz so gut aus. Das liegt aber hauptsächlich daran, dass du in jedem Durchlauf eine Tabelle kopierst und dann mit DELETE nochmal über die (wahrscheinlich) unsortierte Kopie drüber musst.

Das vereinfachte Problem, das du schilderst, sieht für mich sehr nach JOIN aus. Geht es denn damit nicht in einem Select? Man sollte hier beachten, dass der Transport überflüssiger Daten von DB nach Applikationsserver die Performance auch nach oben treiben kann.

Außerdem könntest du dir mal LOOP AT ... GROUP BY anschauen. Das ist auch eine neuere Funktion für Schleifen und gibt dir die Möglichkeit, die große, äußere Tabelle in kleinen Gruppen zu durchlaufen.

Kleine Anmerkung noch: es ist immer ratsam eine IF ... IS NOT INITIAL-Abfrage um Selects mit FOR ALL ENTRIES zu machen, da bei leerer Tabelle einfach alles geladen wird. Nicht gut ^^
Hi Lausek,
vielen Dank für deine Antwort.

Die Tabelle(n) vorher zu sortieren wäre kein Problem, ich glaube sogar ohne jetzt ins Coding zu schauen, dass das sowieso schon der Fall ist.
Ein JOIN geht leider an der Stelle aus verschiedenen Gründen nicht :-(, das Programm macht "Drumherum" noch einiges mehr als hier in dem Auszug dargestellt...
GROUP BY könnte ggf. eine Option sein, das werde ich mir kommende Woche mal in Bezug auf den Programmkontext genauer anschauen!

Die Abfrage auf INITIAL ist vorhanden, viel nur meiner Faulheit hier Code zu tippen zum Opfer ;-)

Re: Performance

Beitrag von gtoXX (Specialist / 185 / 34 / 31 ) »
schick hat geschrieben:
Spontan kommt mir sowas als Option in den Sinn, ich bin mir aber nicht sicher, ob das wirklich performanter ist... (sonderlich "elegant" ist es ohnehin nicht):

Code: Alles auswählen.

SELECT * 
FROM vbak 
INTO TABLE lt_vbak.

SELECT *
FROM vbap
INTO TABLE lt_vbap
FOR ALL ENTRIES IN lt_vbak.

LOOP AT lt_vbak INTO ls_vbak.

lt_vbap_neu = lt_vbap.
DELETE lt_vbap_neu WHERE vbeln NE lt_vbak-vbeln.

...

CALL FUNCTION 'X'
EXPORTING
TABLES 
position = lt_vbap_neu
EXCEPTIONS.

...

ENDLOOP.
Ich freue mich über Anregungen! :-)


Randbemerkung:
Sowohl "SELECT *" als auch die "tollen" Bezeichner ala "lt_vbak" sind nur hier als Platzhalter, im richtigen Programm ist das anders gelöst...

Edit:
Releasestand ist übrigens 7.4

Es ist natürlich schwer eine 100%tige Aussage zu treffen, was besser ist ohne das Programm zu kennen.

Beispiel : Werden keine Werte tatsächlich von VBAK gebraucht, wäre ein Subquery beim Select auf die VBAP schon mal besser.

Wenn VBAK explizit sortiert wird im Programm, würde ich schon mal gleich in einen Tabelle mit einem sorted-Tabellentyp selektieren. Aber auch diese Frage ist bei FOR ALL ENTRIES nur relevant, wenn auf den Feldern, auf die in VBAP selektiert wird ein Index liegt.

Ob der FuBA eine Gruppe aus Group by aktzeptiert kann ich gerade mangels aktuellem System nicht sagen.

Das obige Beispiel mit dem Delete ist jedenfalls denkbar schlecht. ( 1. Speicherverbrauch ) : Du kopierst erst n-Zeilen in eine interne Tabelle ( und zwar jedes mal die "riesige" ursprüngliche interne Tabelle um ( 2. Performance ) : n-mal nicht benötigte Zeilen zu löschen.

Ein Zahlenbeispiel : Gegeben seien 1 Mio Kundenaufträge mit jeweils 1 Position : VBAK hat 1 Mio. Zeilen. VBAP liefert dazu exakt auch 1 Mio. Zeilen. Das Programm braucht also Speicher für 1 Mio VBAP Zeilen. Bei dem ursprünglichen Coding würde jedoch nur Speicher für exakt 1 VBAP-Zeile gebraucht. 2. Du löscht 999.999 mal 999.999 unbenötigte VBAP Zeilen.

Gruß,

GTO
"Code lügt nicht ^^"

Seite 1 von 1

Vergleichbare Themen

3
Antw.
2329
Views
Performance von INE vs. EEQ
von Birdy » 14.08.2013 11:35 • Verfasst in ABAP® für Anfänger
3
Antw.
2407
Views
Performance
von SAP_ENTWICKLER » 19.02.2018 07:06 • Verfasst in SAP HANA für Anfänger
2
Antw.
1763
Views
SQL und Performance
von Hagbard » 24.11.2005 08:51 • Verfasst in ABAP® für Anfänger
9
Antw.
10666
Views
Performance-Tip
von Steff » 04.09.2004 13:47 • Verfasst in Tips + Tricks & FAQs
1
Antw.
1630
Views
IDOC-Performance
von Thomas R. » 18.09.2007 15:02 • Verfasst in Basis

Über diesen Beitrag


Unterstütze die Community und teile den Beitrag für mehr Leser und Austausch

Newsletter Anmeldung

Keine Beiträge verpassen! Wöchentlich versenden wir lesenwerte Beiträge aus unserer Community.
Die letzte Ausgabe findest du hier.
Details zum Versandverfahren und zu Ihren Widerrufsmöglichkeiten findest du in unserer Datenschutzerklärung.

Unbeantwortete Forenbeiträge

Zwischensumme Adobe Forms
vor 4 Tagen von Lucyalison 1 / 72
Group Items auf einer Filterbar
vor einer Woche von Bright4.5 1 / 111
tRFC Transaktionen SM58
vor 4 Wochen von A6272 1 / 141