Code: Alles auswählen.
SELECT a~auart AS baauart a~vbeln AS bavbeln a~erdat AS baerdat
a~kunnr AS bakunnr a~vkbur AS bavkbur a~vkorg AS bavkorg
a~vtweg AS bavtweg
b~vbeln AS ipvbeln b~erdat AS iperdat
b~wadat_ist AS ipwadat_ist
d~matnr AS bpmatnr d~arktx AS bparktx d~kwmeng AS bpkwmeng
d~netwr AS bpnetwr d~uepos AS bpuepos
e~lfimg AS islfimg e~vbeln AS zvbeln e~posnr AS zposnr
f~bzirk AS bdbzirk
INTO CORRESPONDING FIELDS OF TABLE gt_all
FROM ( ( ( likp AS b INNER JOIN lips AS e
ON b~vbeln = e~vbeln )
INNER JOIN vbak AS a
ON a~vbeln = e~vgbel )
INNER JOIN vbap AS d
ON d~vbeln = e~vgbel
AND d~posnr = e~vgpos )
INNER JOIN vbkd AS f
ON f~vbeln = d~vbeln
AND f~posnr = d~posnr
WHERE a~vbeln IN so_vbeln
AND a~auart IN so_auart
AND a~erdat IN so_erdat
AND a~kunnr IN so_kunnr
AND a~vkbur IN so_vkbur
AND a~vkorg IN so_vkorg
AND a~vtweg IN so_vtweg
AND d~matnr IN so_matnr
AND d~uepos IN so_uepos
AND f~bzirk IN so_bzirk
AND b~vbeln IN so_lbeln
AND b~erdat IN so_lerda
AND b~wadat_ist IN so_lwati
AND d~arktx IN so_arktx
AND d~netwr IN so_netwr
AND d~kwmeng IN so_kwmen
AND e~lfimg IN so_lfimg.
DeathGuardian hat geschrieben:Wieso ist es auf dem Entwicklungssystem schneller als auf dem Testsystem?
Ich weis ja nicht, wie es bei euch aussieht, aber bei uns hat das E-System eher weniger bis gar keine Daten und das Testsystem ist verhältnismässig Produktivsystem nah.
Sprich E hat weniger Daten deshalb auch schneller, weil weniger zu selectieren.
Das ist wohl wahr, aber das das ganze gleich derart ausartet?![]()
Ich dachte JOINs sind immer schneller, als wenn man jede DB-Tabelle einzeln selektiert?!
In der Regel ja, aber die Regel trifft nicht immer zu.
Du machst aktuell einen JOIN von LIPS der auf VBAK und VBAP gleichzeitig geht.
Mach daraus mal ein JOIN der von LIPS auf VBAP und dann von VBAP auf VBAK geht.
Das wird glaub ein wenig was raushollen und auch dafür sorgen, das das Ergbnis genauer wird.
Also werde ich den Select soweit ändern, dass ich nicht 2mal die Lips hernehme.
Dann sieht der FROM Teil so aus:Eventuell würden auch ein paar Index helfen.Code: Alles auswählen.
FROM ( ( ( likp AS b INNER JOIN lips AS e ON b~vbeln = e~vbeln ) INNER JOIN vbap AS d ON d~vbeln = e~vgbel AND d~posnr = e~vgpos ) INNER JOIN vbak AS a ON a~vbeln = d~vbeln ) INNER JOIN vbkd AS f ON f~vbeln = d~vbeln AND f~posnr = d~posnr
Hallo Krueger,Krueger hat geschrieben:Mein Vorschlage.../...Ich würde es mal so versuchen:
1.) INTO CORRESPONDING FIELDS OF TABLE gt_all
in der internen Tabelle GT_ALL genau die Felder aufnehmen, die ich in dem Join auch nur brauche, damit diese "INTO CORRESPONDING" wegfällt.
Lesen der KOPFtabellen in interne Tabellen und anschliessend ein Select auf die POSITIONSTabellen mit "FOR ALL ENTRIES".
Meine Erfahrungen mit JOIN's: Wenn die Joins zu gross werden, geht die Performance in die Knie und eine Select... Endselect ist performanter.
Das händeln der riesigen internen Tabellen wirkt sich zu sehr negativ aus.
Wie bereits erwähnt, evtl. mit bedacht INDEXe in der SE11 auf die DB anlegen.
Edit: "VERSUCH MACHT KLUCH!!!"
Schlechte Angewohnheit, würde ich versuchen mit abzugewöhnenDas Corresponding könnte ich weg lassen, die int. Tabelle hat nur die Felder die selektiert werden sollenIch schreib das nur aus gewohnheit hin.
Die User sollten "gezwungen werden" die Datenselektion einzugrenzen.Wenn ich die LIKP in eine int. Tabelle lese...ist das nicht genauso unperformant dann? Habe gerade nachgeschaut, da stehen 10mio Sätze drin. Wenn ich dann auch noch die VBAK in eine int. Tabelle lese killt mich womöglich der Admin![]()
Versuch macht klug: Mach einfach eine Prog. mit Join und eines mit Select ... Endselect.Ich würd die Joins ja wieder abschaffen, aber sehr wohl ist mir nicht dabei, dass ich dann über eine int. Tabelle mit knapp 10mio datensätze loop.
In diesen Selektionen sollte möglich VIEL eingegrenzt werden.WHERE a~vbeln IN so_vbeln
AND a~auart IN so_auart
AND a~erdat IN so_erdat
AND a~kunnr IN so_kunnr
AND a~vkbur IN so_vkbur
AND a~vkorg IN so_vkorg
AND a~vtweg IN so_vtweg
AND d~matnr IN so_matnr
AND d~uepos IN so_uepos
AND f~bzirk IN so_bzirk
AND b~vbeln IN so_lbeln
AND b~erdat IN so_lerda
AND b~wadat_ist IN so_lwati
AND d~arktx IN so_arktx
AND d~netwr IN so_netwr
AND d~kwmeng IN so_kwmen
AND e~lfimg IN so_lfimg.
Code: Alles auswählen.
FORM select_data .
DATA:
lf_vbfavbeln TYPE vbeln_von,
lf_anzi TYPE i,
lf_anzs TYPE string,
lf_fehler TYPE c.
SELECT a~auart AS baauart a~vbeln AS bavbeln a~erdat AS baerdat
a~kunnr AS bakunnr a~vkbur AS bavkbur a~vkorg AS bavkorg
a~vtweg AS bavtweg
b~matnr AS bpmatnr b~arktx AS bparktx b~kwmeng AS bpkwmeng
b~netwr AS bpnetwr b~uepos AS bpuepos b~posnr AS zposnr
f~bzirk AS bdbzirk
INTO CORRESPONDING FIELDS OF TABLE gt_all "gt_vkbel
FROM ( vbak AS a INNER JOIN vbap AS b
ON a~vbeln = b~vbeln )
INNER JOIN vbkd AS f
ON f~vbeln = b~vbeln
AND f~posnr = b~posnr
WHERE a~erdat IN so_erdat
AND a~kunnr IN so_kunnr
AND a~auart IN so_auart
AND a~vkbur IN so_vkbur
AND a~vkorg IN so_vkorg
AND a~vtweg IN so_vtweg
AND b~matnr IN so_matnr
AND b~uepos IN so_uepos
AND b~arktx IN so_arktx
AND b~netwr IN so_netwr
AND b~kwmeng IN so_kwmen
AND f~bzirk IN so_bzirk
ORDER BY a~vbeln b~posnr.
LOOP AT gt_all INTO gs_all.
CLEAR lf_fehler.
SELECT c~vbeln AS ipvbeln c~erdat AS iperdat
c~wadat_ist AS ipwadat_ist
d~lfimg AS islfimg "d~vbeln AS zvbeln d~posnr AS zposnr
INTO CORRESPONDING FIELDS OF gs_all
FROM likp AS c INNER JOIN lips AS d
ON c~vbeln = d~vbeln
WHERE d~vgbel = gs_all-bavbeln
AND d~vgpos = gs_all-zposnr
AND c~vbeln IN so_lbeln
AND c~erdat IN so_lerda
AND c~wadat_ist IN so_lwati
AND d~lfimg IN so_lfimg.
* Name des Auftraggebers(Kunde) ermitteln
SELECT SINGLE name1 AS zkunam
FROM kna1
INTO CORRESPONDING FIELDS OF gs_all
WHERE kunnr = gs_all-bakunnr.
* Fakturadaten ermitteln. Lieferungsbezogene Rechnungs-Faktura ('M').
* Wenn nix gefunden, wird der ganze Datensatz nicht mehr ausgegeben.
SELECT SINGLE vbeln
FROM vbfa
INTO lf_vbfavbeln
WHERE vbelv = gs_all-ipvbeln
AND posnv = gs_all-zposnr
AND vbtyp_n = 'M'.
IF sy-subrc EQ 0.
SELECT SINGLE vbeln AS brvbeln erdat AS brerdat
FROM vbrk
INTO CORRESPONDING FIELDS OF gs_all
WHERE vbeln = lf_vbfavbeln
AND vbeln IN so_rbeln
AND erdat IN so_rerda.
IF sy-subrc NE 0.
lf_fehler = 'X'.
ENDIF.
ELSE.
lf_fehler = 'X'.
ENDIF.
IF lf_fehler IS INITIAL.
MODIFY gt_all FROM gs_all.
ENDIF.
ENDSELECT.
IF sy-subrc <> 0 OR lf_fehler = 'X'.
DELETE gt_all INDEX sy-tabix.
ENDIF.
ENDLOOP.
ENDFORM. " select_data
Weißt du ob der Index von der VBAK gezogen wird?MarkusW hat geschrieben: Wäre dankbar für weitere Tips und Hilfen!
Vielleicht ist ja hier einer da, der sich im SD-Bereich gut auskennt
dem kann ich so nicht zustimmen.JHM hat geschrieben:...
MOVE-CORRESPONDING ist immer unperformant und gehört verboten, ist nur etwas für faule Programmierer.
...
Meine Sichtweise bezog sich auf ein reinen Z-Report, der vorgegebene Daten liest. Bei uns wird teilweise von Kollegen in solchen Fällen mit SELECT * INTO CORRESPONDING gearbeitet, wobei nicht alle Felder benötigt werden. Wenn solche Programme dann performence Probleme haben ist natürlich die Hardware schuld.ereglam hat geschrieben: es hängt immer von der Art der Anwendung ab, welche Sprachkonstrukte sinnvoll sind.
Etwas pauschal zu verdammen, weil man die gesamte Bandbreite der Anwendungen nicht kennt, halte ich für unangebracht.