Performance-Problem bei SELECT

Alles rund um die Sprache ABAP®: Funktionsbausteine, Listen, ALV
19 Beiträge • Seite 1 von 2 (current) Nächste
19 Beiträge Seite 1 von 2 (current) Nächste

Performance-Problem bei SELECT

Beitrag von Charadin (Specialist / 148 / 0 / 0 ) »
Hallo zusammen,

ich analysiere gerade einen ABAP-Report, der beim Ausführen relativ lange braucht. Soweit ich gesehen habe, sind die Datenbankzugriffe die Ursache für das Problem. Ich habe erstmal alle Joins entfernt, trotzdem braucht es noch relativ lange.

Ein Beispiel:

Diese Abfrage:

Code: Alles auswählen.

  SELECT *
    FROM db_tab
    INTO TABLE it_tab
    WHERE einri IN pa_einri
         AND NOT storn = 'X'      
         AND typ  =  1
          OR typ  =  3.
braucht ca. 4 Minuten; insgesamt hat die abgefragte Tabelle 2 Mio. Einträge, durch die Einschränkung bleiben ca. 65000 Einträge übrig. Ist so eine lange Laufzeit normal bzw. welche Ursachen kann das haben?
Nach diesem SELECT habe ich übrigens vom System die Meldung "Speicher wird knapp..." bekommen. Kann das irgendwie damit zusammenhängen?
Gruß,
Charadin

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


Beitrag von poldi (Specialist / 116 / 0 / 0 ) »
Hallo Charadin,

um hier Aussagen treffen zu können, müßte man den Quelltext sehen sowie die gelesenen Tabellen mit der SE11 (Stichwort: Indizes). Joins sind übrigens in der Regel gut. "Speicher wird knapp ..": Die gelesenen Daten werden in internen Tabellen gespeichert und die Datenmengen sind sehr "groß".

Viele Grüße
Wilfried
Wir sind lustig und haben es gar nicht nötig!

Beitrag von Charadin (Specialist / 148 / 0 / 0 ) »
Hallo poldi,

vielen Dank für Deine Antwort.

Der betroffene SELECT ist dieser:
(ich habe erstmal alle JOINS entfernt und die DB-Abfrage auf eine DB beschränkt...)

Code: Alles auswählen.

  SELECT *
    FROM nbew
    INTO TABLE it_aktu
    WHERE einri IN einricht
      AND ( bewty = 1
       OR   ( bewty = 3
      AND    ( bwart = '04'
       OR      bwart = '06'
       OR     ( bwart = ''
      AND NOT   orgpf = '' ) ) ) )
      AND bwidt <= datum
      AND NOT storn = 'X'.
Die Tabelle NBEW hat insgesamt 103 Felder, die Schlüsselfelder sind MANDT, EINRI, FALNR und LFDNR. Mit Indizes kenne ich mich leider nicht so gut aus,müsste ich für die Tabelle NBEW einen Index anlegen, der alle abgefragten Felder enthält?

Die interne Tabelle enthält nach dem SELECT wie gesagt ~65.000 Einträge, das dürfte meiner Meinung nach doch noch nicht dazu führen, dass der Speicher knapp wird, oder?
Gruß,
Charadin

Beitrag von poldi (Specialist / 116 / 0 / 0 ) »
Hallo Charadin,

Speicherheitknappheit kann ich mir hier auch nicht vorstellen. Die Tabelle NBEW gibt es bei mir im System nicht. Statt SELECT * sollte man nur die Felder lesen, welche benötigt werden. Dazu sollte it_aktu auch entsprechend angepaßt werden. Die WHERE-Klausel ist reichlich unübersichtlich und da sollte ein Index auch wenig helfen. NOT-Bedingungen können auch nicht über den Index verarbeitet werden. Entweder mit mehreren einfacherenSELECTs lesen und immer an die it_aktu anhängen oder vielleicht hilft auch folgendes:

select feld1 feld 2 ... feldn from nbew appending corresponding fields
of table it_aktu
where einri in einricht
and bwidt <= datum
and not storn = 'X'.
("and bewty = 1 or bewty = 3" kann ich mir in der WHERE-Klausel auch noch vorstellen und viielleicht kann man noch "not storn = 'X'" besser durch "storn = space" ersetzen.)
Außerdem definiert man sich in der it_aktu ein Feld delkz(1). Dann wertet man in der Tabelle die Felder bewty, bwart und orgpf aus. Sind die Bedingungen nicht erfüllt setzt man delkz auf "X" und nach dem LOOP ... ENDLOOP sagt man: delete it_aktu where delkz = 'X'. Dieses DELETE ist besser und schneller als ein DELETE im LOOP ... ENDLOOP.

einri an erster Stelle in der WHERE-Klausel ist übrigens in Ordnung.

Ich hoffe, das hilft etwas wieter.

Viele Grüße
Wilfried
Wir sind lustig und haben es gar nicht nötig!

Beitrag von Charadin (Specialist / 148 / 0 / 0 ) »
Hallo Wilfried,

danke für die vielen Tipps, werde da mal ein bisschen herumprobieren und schauen, ob sich die Performance verbessert...
Gruß,
Charadin

Beitrag von khb (Specialist / 184 / 7 / 1 ) »
Hallo Charadin,

bei mir gab es einmal ein ähnliches (?) Speicherplatzproblem, an die genaue Meldung erinnere ich mich nicht mehr. Gemeinsam mit der Basis haben wir damals festgestellt, dass interne benutzerbezogene Speicherbereiche nicht freigegeben wurden.

Daraufhin habe ich den Teil zur Datenselektion im Hintergrund gelegt. Der Aufruf des Reports sowie die Auswertung können jedoch online erfolgen.

lg khb

Beitrag von Charadin (Specialist / 148 / 0 / 0 ) »
Hallo khb,

danke Dir für den Hinweis.
Muss ich dann für den Teil der Datenselektion einen eigenen Report schreiben und den dann als Job ausführen? Oder wie kann ich veranlassen, dass die Datenselektion im Hintergrund ausgeführt wird?

Hat Eure Basis damals eigentlich die internen benutzerbezogenen Speicherbereiche freigegeben?
Gruß,
Charadin

Beitrag von khb (Specialist / 184 / 7 / 1 ) »
Hallo Charadin,

ich habe den ursprünglichen Report folgendermaßen aufgeteilt:

1 Report mit dem Selektionsbildschirm zum Fehlerabfang der eingegebenen Daten. Dort wird dann mit FuBa Job_open der Job angelegt, mit submit ... via job der Selektionsreport übergeben und zum Schluß noch mit dem FuBa Job_close der Job wieder geschlossen.

Die Datenselektion (Start-of-Selection) erfolgt im übergebenen Report, die Daten werden in der INDX gespreichert. An den User wird eine Meldung gesendet, wenn dieser Report abgeschlossen ist.

Die Auswertung (End-of-Selection) erfolgt über einen 3. Report, der die Daten aus der INDX wieder ausliest.

Da das Coding für die Datenselektion und -verarbeitung bereits vorhanden war, ist der Aufwand auch nicht so groß, die gemeinsamen Datendeklarationen können über Includes bereitgestellt werden.

Falls Du noch weitere Infos brauchst, melde Dich.

hth khb

PS.:
Die internen Speicherbereiche wurden automatisch freigegeben, wenn die Liste wieder verlassen wurde. Bei diesem neuen Ablauf haben wir wieder kontrolliert: der Speicherplatz wird zwar benötigt (es war aber weniger) und wenn der Report mit der Selektion beendet ist, wird er wieder freigegeben. Der Report, der die INDX ausliest, bereitet keine Speicherprobleme.
Außerdem war die Laufzeit bei der Datenselektion nun kürzer.

Und der Anwender freut sich auch: er kann zwischendurch weiterschaffen und kriegt eine Meldung.

Beitrag von Charadin (Specialist / 148 / 0 / 0 ) »
dann werde ich mal versuchen, mein Programm ähnlich aufzubauen...

Danke für die ausführliche Antwort, hilft mir wirklich weiter... :D
Gruß,
Charadin

Beitrag von khb (Specialist / 184 / 7 / 1 ) »
Hallo Charadin,

gerne geschehen. Ach ja, das hatt ich noch vergessen: die message gibst Du im Report, der übergeben wird, folgendermaßen aus:

call function 'SO_EXPRESS_FLAG_SET'



lg khb

Beitrag von Charadin (Specialist / 148 / 0 / 0 ) »
Hallo khb,

jetzt habe ich doch noch eine Frage: :wink:

Welche Bedeutung hat die Bereichskennung ar beim EXPORT-/IMPORT-Befehl?

Code: Alles auswählen.

EXPORT obj1 ... objn TO DATABASE dbtab(ar) ID key. 
Die Hilfe sagt dazu nur folgendes:
Die Datenbanktabelle dbtab wird in verschiedene logisch zusammenhängende Gebiete unterteilt ( ar, 2stellige Bezeichnung).
Kann ich diese 2-stellige Bezeichnung selbst wählen? Oder muss ich eine bereits existierende Bereichskennung verwenden? Aber woran erkenne ich dann, welche Bereichskennung bereits genutzt wird?
Gruß,
Charadin

Beitrag von khb (Specialist / 184 / 7 / 1 ) »
Hallo Charadin,

soweit ich weiß, kann die frei gewählt werden.

Ich schreibe die Daten folgendermaßen in die INDX- Datei:

Zuerst bastele ich mir die ID zusammen:
concatenate sy-uname 'TECCMD' 'MARA' into g_id.

Und nun der Export der Tabelle t_artikel in die INDX
export tab = t_artikel to database indx(zz) id g_id.

Beim Import dann analog.

Falls es noch Probleme gibt. melde Dich. Bei mir klappte die Lösung einwandfrei.

lg khb

Beitrag von Charadin (Specialist / 148 / 0 / 0 ) »
bei mir schaut's jetzt so aus:

Code: Alles auswählen.

CALL FUNCTION 'JOB_OPEN'
    EXPORTING
      delanfrep              = 'Y'
*     JOBGROUP               = ' '
      jobname                = 'DATENSELEKTION'
*     SDLSTRTDT              = NO_DATE
*     SDLSTRTTM              = NO_TIME
*     JOBCLASS               =
   IMPORTING
     jobcount               = vc_jcount
*   CHANGING
*     RET                    =
   EXCEPTIONS
     cant_create_job        = 1
     invalid_job_data       = 2
     jobname_missing        = 3
     OTHERS                 = 4.

  SUBMIT znar_statlist_data
    WITH datum = datum
    WITH einricht IN einricht
    WITH pfoe IN pfoe
    VIA JOB 'DATENSELEKTION' NUMBER vc_jcount
    AND RETURN.

  CALL FUNCTION 'JOB_CLOSE'
    EXPORTING
      jobcount                          = vc_jcount
      jobname                           = 'DATENSELEKTION'
*    IMPORTING
*      JOB_WAS_RELEASED                  =
*    CHANGING
*      RET                               =
   EXCEPTIONS
     cant_start_immediate              = 1
     invalid_startdate                 = 2
     jobname_missing                   = 3
     job_close_failed                  = 4
     job_nosteps                       = 5
     job_notex                         = 6
     lock_failed                       = 7
     invalid_target                    = 8
     OTHERS                            = 9.
Wenn ich das 'VIA JOB 'DATENSELEKTION' NUMBER vc_jcount' aus dem SUBMIT rausnehme, wird der Datenselektionsreport aufgerufen, über den Job dagegen wird der Report nicht ausgeführt...

Mache ich da irgendwas falsch?
Gruß,
Charadin

Beitrag von Charadin (Specialist / 148 / 0 / 0 ) »
das war eh klar, kaum stelle ich die Frage ins Forum, entdecke ich den Fehler selber... :wink:

Ich muss beim JOB_CLOSE noch den Parameter "STRTIMMED" setzen, damit der Batch-Job sofort ausgeführt wird...

hab' das ganze jetzt mal am Testsystem laufen lassen, aber irgendwie braucht das ganze länger als vorher ohne Job - kann sich das mit der Anzahl der Datensätze noch umdrehen? Ich werde es mal ausprobieren...
Gruß,
Charadin

Beitrag von Charadin (Specialist / 148 / 0 / 0 ) »
gibt es eigentlich irgendein Kennzeichen, das ich setzten kann, um meinem aufrufenden Report zu sagen "Mache erst weiter, wenn der Job ausgeführt wurde" - scheinbar wird nicht automatisch abgewartet, bis der Job ausgeführt wurde... :?:
Gruß,
Charadin

Vergleichbare Themen

4
Antw.
9325
Views
Performance: SELECT UP TO 1 ROWS vs. SELECT SINGLE
von roman1983 » 04.09.2008 14:29 • Verfasst in ABAP® für Anfänger
14
Antw.
2900
Views
Performance Problem
von ChrissixD » 26.09.2017 09:13 • Verfasst in ABAP® für Anfänger
2
Antw.
1226
Views
Performance Problem
von ChrissixD » 21.11.2017 07:49 • Verfasst in ABAP® für Anfänger
70
Antw.
18066
Views
Performance-Problem
von cuncon » 27.02.2018 07:41 • Verfasst in ABAP® für Anfänger
8
Antw.
4546
Views
Speicher & Performance Problem bei XML einlesen
von Zubasa » 15.06.2011 13:48 • Verfasst in ABAP® für Anfänger

Ü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

Daten an Tabelle binden
vor 18 Stunden von Bright4.5 1 / 400
aRFC im OO-Kontext
vor 4 Wochen von ralf.wenzel 1 / 2046
Hilfe bei SWEC/SWE2
letzen Monat von retsch 1 / 8642