Select auf 2 große Tabellen

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

Select auf 2 große Tabellen

Beitrag von ann_bine (ForumUser / 5 / 0 / 1 ) »
Hallo zusammen,
ich will zwei Tabellen (mit jeweils ca.30 Mio Einträgen) joinen. Das Problem hierbei ist, dass das Verbindungsfeld der beiden Tabellen in beiden Tabellen kein Schlüsselfeld ist und in einer der beiden Tabellen kann der Wert in drei verschiedenen Feldern stehen/ vorkommen. Deshalb ist ein left outer Join leider nicht möglich. Alternative hierzu war FOR ALL ENTRIES. Problem bei meinem Code ist jedoch, dass der zweite Select zu lange dauert und somit ein Laufzeitfehler auftritt.
Hier mal das Coding:

Code: Alles auswählen.

SELECT
        zzbuchid
        zzzusid_lang
        zzvsnr
        zznamvn
        zzbuchtext1
        zzbuchtext2
        zz_provartabr
        zzgsfnr
        zzgsfnr2
        zzgsfnr3
        zzfitransdat
        zzbuchdat
        zzfaellig
        gpart
        due_conamnt

      FROM zicmww_docse UP TO p_maxl ROWS INTO CORRESPONDING FIELDS OF TABLE gt_docse
      WHERE
            ( zzgsfnr  IN s_gsfnr   OR
              zzgsfnr2 IN s_gsfnr   OR
              zzgsfnr3 IN s_gsfnr ) AND
              zzbuchid IN s_anr     AND
              zzvsnr   IN s_vsnr    AND
          zzfitransdat IN s_fitra   AND
                 zzmig = space.

* Wenn keine DOCSE-Einträge vorhanden, Abbruch, um FullTableScan der VVSCPOS zu verhindern (wg. FOR ALL ENTRIES)
    IF gt_docse IS INITIAL.
      MESSAGE i018(zcdi1n_reports).
      LEAVE TO TRANSACTION 'ZICM_DOCSE'.
    ELSE.

* Lese VVSCPOS...
*...gemäß Selektionskriterien
*...nur HVORG gemäß Rangestabelle -> zcdi1n_hvorg_sel (doppelte Datensätze verhindern)
*...für alle in gt_docse enthaltenen GSFNR
*  ...Ein Join über die Tabellen nicht möglich, wegen: Geschäftsfallnummer steht
*  - je nach HVORG - im Feld zzgsfnr, zzgsfnr2 oder zzgsfnr3

      SELECT zz_vtwegabr
             zz_provart
             h_hkont
             zz_remunabr
             gsfnr
             FROM vvscpos   UP TO p_maxl ROWS INTO CORRESPONDING FIELDS OF TABLE gt_vvscpos
             FOR ALL ENTRIES IN gt_docse
             WHERE    hvorg IN gt_hvorg_sel     AND
                    ( gsfnr = gt_docse-zzgsfnr  OR
                      gsfnr = gt_docse-zzgsfnr2 OR
                      gsfnr = gt_docse-zzgsfnr3 ) AND
                      gsfnr IN  s_gsfnr         AND "nur GSFNRn gemäß Selektionskriterien
                    h_hkont     IN s_hkont      AND
                    zz_remunabr IN s_remun.

    ENDIF.

Hoffe mir kann jemand helfen wie man die Performance des zweiten Selects verbessern kann:) und Danke schon mal im Voraus

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


Re: Select auf 2 große Tabellen

Beitrag von ewx (Top Expert / 4844 / 311 / 640 ) »
ganz klar: SELECT-Zusatz PACKAGE-SIZE
Bin mir nicht sicher, ob das mit JOIN funktioniert.
Falls ja, auf jeden Fall mal ausprobieren PACKAGE-SIZE mit JOIN über beide Tabellen und SELECT FOR ALL ENTRIES mit zwei SELECTs.

Re: Select auf 2 große Tabellen

Beitrag von Alexander D. (Expert / 682 / 30 / 84 ) »
hallo Ann_bine,
ann_bine hat geschrieben:Das Problem hierbei ist, dass das Verbindungsfeld der beiden Tabellen in beiden Tabellen kein Schlüsselfeld ist und in einer der beiden Tabellen kann der Wert in drei verschiedenen Feldern stehen/ vorkommen.
müssen die Daten denn unbedingt in einem Join gelesen werden? Du könntest drei SELECTS auf jeweils eins der Schlüsselfelder absetzen. Über die Transaktion ST05 könnte man einen SQL-Trace anlegen, prüfen auf welche Art auf die Tabelle zugegriffen wird und ggf. den Tabellen noch zur Unterstützung einen Index verpassen

gruss
Alexander
schöne Grüße
Alexander

ECC 6.0 EHP 7

Re: Select auf 2 große Tabellen

Beitrag von ann_bine (ForumUser / 5 / 0 / 1 ) »
Hallihallo,

danke für Eure Antworten.

@ewx:
wie geht das mit dem Zusatz Package-sizes genau? Muss ich dafür nicht eine Select-Schleife machen und dann jedes Package direkt verarbeiten?
Ich selektiere momentan im ersten Schritt Daten aus Tabelle A in eine itab A. Im zweiten SChritt selektiere ich aus Tabelle B mit For all entries wieder mit ArrayFetch in itab B.

@Alexander
das mit den 3 Joins hintereinander habe ich schon probiert - das ist leider daran gescheitert, dass in der where-Bedingung beim Left-Outer-Join nur Felder einer Tabelle (ob es die linke oder rechte ist, weiß ich jetzt nicht mehr) vorkommen dürfen. Ich habe aber Einschränkungen auf beide Tabellen.

Der Select auf Tabelle A läuft schnell. Nur wenn ich dort ca. 5000 Treffer aufwärts habe und dann mit FOR ALL ENTRIES aus Tabelle B selektieren will, gibt es einen Laufzeitfehler. Die Zugriffe scheinen sich so zu potenzieren, dass es das System nicht packt.

Re: Select auf 2 große Tabellen

Beitrag von a-dead-trousers (Top Expert / 4395 / 223 / 1182 ) »
Ich Übernehm einfach mal das Antworten ;)
ann_bine hat geschrieben:@ewx:
wie geht das mit dem Zusatz Package-sizes genau? Muss ich dafür nicht eine Select-Schleife machen und dann jedes Package direkt verarbeiten?
Schau dir mal den Befehl OPEN CURSOR an
ann_bine hat geschrieben: @Alexander
das mit den 3 Joins hintereinander habe ich schon probiert - das ist leider daran gescheitert, dass in der where-Bedingung beim Left-Outer-Join nur Felder einer Tabelle (ob es die linke oder rechte ist, weiß ich jetzt nicht mehr) vorkommen dürfen. Ich habe aber Einschränkungen auf beide Tabellen.
Ich denke hier wäre ein INNER JOIN angebrachter. Tab A <-> Tab B (On Feld 1) / Tab A <-> Tab B (On Feld 2) / Tab A <-> Tab B (On Feld 3) und dann alle drei Ergebnisse im Programm zusammenführen.
ann_bine hat geschrieben: Der Select auf Tabelle A läuft schnell. Nur wenn ich dort ca. 5000 Treffer aufwärts habe und dann mit FOR ALL ENTRIES aus Tabelle B selektieren will, gibt es einen Laufzeitfehler. Die Zugriffe scheinen sich so zu potenzieren, dass es das System nicht packt.
Hier gibt die Hilfe einige wichtige Infos:
FOR ALL ENTRIES wandelt alle Einträge in entsprechende SQL-WHERE-Befehle um. Wenn das Statement jetzt zu lang wird (liegt glaub ich standardmäßig so bei 2 MB) dann kann die Query nicht von der Datenbank verarbeitet werden. Ist aber auch abhängig von der Konfiguration, weil die DB-Schnittstelle bei einigen Befehlen die Möglichkeit bietet die Querys in kleinere Pakete zu zerlegen bevor die DB die Anfrage erhält.

lg ADT
Theory is when you know something, but it doesn't work.
Practice is when something works, but you don't know why.
Programmers combine theory and practice: Nothing works and they don't know why.

ECC: 6.18
Basis: 7.50

Re: Select auf 2 große Tabellen

Beitrag von ewx (Top Expert / 4844 / 311 / 640 ) »
a-dead-trousers hat geschrieben:Ich Übernehm einfach mal das Antworten ;)
ann_bine hat geschrieben:@ewx:
wie geht das mit dem Zusatz Package-sizes genau? Muss ich dafür nicht eine Select-Schleife machen und dann jedes Package direkt verarbeiten?
Schau dir mal den Befehl OPEN CURSOR an
lg ADT
Der Zusatz ist auch beim SELECT verfügbar. F1 sollte ausreichend Hilfe bieten.
Ansonsten hier: http://tricktresor.de/content/index.php ... 30&aID=524
Und hier: http://tricktresor.de/content/index.php ... 37&aID=315

Folgende Benutzer bedankten sich beim Autor ewx für den Beitrag:
Pinguincommander


Re: Select auf 2 große Tabellen

Beitrag von a-dead-trousers (Top Expert / 4395 / 223 / 1182 ) »
ewx hat geschrieben:Der Zusatz ist auch beim SELECT verfügbar. F1 sollte ausreichend Hilfe bieten.
:oops:

Folgende Benutzer bedankten sich beim Autor a-dead-trousers für den Beitrag:
Pinguincommander

Theory is when you know something, but it doesn't work.
Practice is when something works, but you don't know why.
Programmers combine theory and practice: Nothing works and they don't know why.

ECC: 6.18
Basis: 7.50

Re: Select auf 2 große Tabellen

Beitrag von ann_bine (ForumUser / 5 / 0 / 1 ) »
In der Zwischenzeit habe ich mit dem PACKAGE SIZE-Zusatz bei SELECT, mit Indexen und auch noch mal Joins experimentiert. Trotz allem gibt es noch immer einen Time-Out. Und mit einem Join lassen sich die vorherrschenden Bedingungen nicht wie gewünscht abbilden :cry:

Jetzt habe ich gelesen, das FOR ALL ENTRIES ab 1000 Einträge in der Treibertabelle keine gute Performance mehr hat. Heißt das, ich muss den Anwender zwingen, die Selektion so weit einzugrenzen, dass in der Treibertabelle nicht mehr als 1000 Einträge stehen?

Folgende Benutzer bedankten sich beim Autor ann_bine für den Beitrag:
Pinguincommander


Re: Select auf 2 große Tabellen

Beitrag von a-dead-trousers (Top Expert / 4395 / 223 / 1182 ) »
hi!

Du könntest noch versuchen bei der Treibertabelle (FOR ALL ENTRIES) wirklich nur die Felder zu selektieren, die bei der zweiten Abfrage benötigt werden. (z.B. nur die Schlüsselfelder) Damit lässt sich vorallem die DATENMENGE die von der DB übertragen wird sehr reduzieren.
Wenn du dann das Ergebnis der zweiten Abfrage hast, kannst du daraus die Abfragebedingung für die evtl. benötigten zusätzlichen Felder der ersten Tabelle ermitteln (SORT, DELETE ADJACENT DUPLICATES)
Die hier bereits erwähnte PACKAGE SIZE ist eigentlich nur sinnvoll, wenn du zwischendurch die bereits selektierten Daten weiterverarbeiten kannst um den Arbeitsspeicher des Appl.Servers zu schonen. Außerdem kannst du auf diese Weise "besser" dein Programm debuggen, weil selbst bei großen Datenselektionen das Programm "anhalten" kann und du nicht auf die komplette Ausführung des Statements warten musst.

Bei großen Datenmenge wirst du aber vermutlich nicht um eine Hintergrund-Ausführung deines Reports herumkommen.
Möglichkeiten wie man die Daten dann ablegen/weiterverarbeiten kann:
- Die ermittelten Daten in einer eigenen Tabelle ablegen, damit die User dann nur noch (z.b. mit einem zweiten Report) diese aufbereiteten Daten auslesen müssen.
- Daten in einer (Excel-/CSV-)Datei auf dem Appl.Server ablegen
- Daten in die Spoolliste ausgeben

lg
ADT

Folgende Benutzer bedankten sich beim Autor a-dead-trousers für den Beitrag:
Pinguincommander

Theory is when you know something, but it doesn't work.
Practice is when something works, but you don't know why.
Programmers combine theory and practice: Nothing works and they don't know why.

ECC: 6.18
Basis: 7.50

Re: Select auf 2 große Tabellen

Beitrag von JHM (Top Expert / 1197 / 1 / 197 ) »
ann_bine hat geschrieben:Jetzt habe ich gelesen, das FOR ALL ENTRIES ab 1000 Einträge in der Treibertabelle keine gute Performance mehr hat. Heißt das, ich muss den Anwender zwingen, die Selektion so weit einzugrenzen, dass in der Treibertabelle nicht mehr als 1000 Einträge stehen?
Die Aussage stimmt so nicht ganz, es kommt ein wenig darauf an, wie man FOR ALL ENTRIE verwendet bzw. die Treibertabelle füllt.

Die Treibertabelle sollte jeden Wert pro Feld, welches in der WHERE-Clause verwendet wird, nur einmal beinhalten. SAP generiert sonst die immer gleiche Where-Bedingungen und sendet diese an die DB. Die Ergebnisse der einzelen Abfragen wird in SAP gesammelt und erst zum Ende der Ausführung gefilltert. Mehr dazu hier: http://scn.sap.com/community/data-wareh ... s-disaster

Eine Verwendung wie hier:

Code: Alles auswählen.

 WHERE    hvorg IN gt_hvorg_sel     AND
                    ( gsfnr = gt_docse-zzgsfnr  OR
                      gsfnr = gt_docse-zzgsfnr2 OR
                      gsfnr = gt_docse-zzgsfnr3 )
geht dann nochmal zusätzlich auf die Perfomenz, da du immer wieder eine Abfrage auf gsfnr = space machts (wie im o.g. Link bereits erklärt).

Am besten du baust wirklich drei Selects auf, in dem du die Tabellen jeweils Joinst und dann je Select nur eins der Felder: ZZGSFNR, ZZGSFNR2 oder ZZGSFNR3 verprobst.
Gruß Hendrik

Re: Select auf 2 große Tabellen

Beitrag von Pinguincommander (ForumUser / 88 / 62 / 2 ) »
hi, was ich gemacht habe um die performance meiner programme zu verbessern, war ich habe mir die benötigten tabellen komplett gezogen also SELECT * FROM <DB>.
dann hab ich das ganze sortiert also sort table ascending und danach die eine tabelle abgeloopt und die in der anderen einen search table ausgeführt wichtig ist dabei der zusatz BINARY SEARCH.
dadurch hab ich die laufzeit meines programms von 70 minuten gedrückt auf geschlagene 2 minuten, also das lohnt sich wirklich, die frage ist natürlich ob du immer einen datensatz brauchst oder ob du je nachdem mehrere brauchst, wenn du viele ergebniss datensätze hast lohnt sich die ganze sache ansonsten dauert der select relativ lange.
ich hoffe ich habe mich verständlich ausgedrückt und konnte dir helfen, sollte irgendwas unklar sein kannst du einfach nachfragen, falls dich meine lösung interessiert.

Re: Select auf 2 große Tabellen

Beitrag von Alexander D. (Expert / 682 / 30 / 84 ) »
Pinguincommander hat geschrieben: ich habe mir die benötigten tabellen komplett gezogen also SELECT * FROM <DB>
Bei kleineren Tabellen mag das funktionieren, bei der Aufgabe
ich will zwei Tabellen (mit jeweils ca.30 Mio Einträgen) joinen
wird es aber bestimmt performanter gehen als 2X SELECT 30 Mio * FROM <DB> mit anschliessendem LOOP darüber
schöne Grüße
Alexander

ECC 6.0 EHP 7

Re: Select auf 2 große Tabellen

Beitrag von Pinguincommander (ForumUser / 88 / 62 / 2 ) »
Alexander D. hat geschrieben: wird es aber bestimmt performanter gehen als 2X SELECT 30 Mio * FROM <DB> mit anschliessendem LOOP darüber
Nunja wie gesagt, hat mir das ein Kollege gesagt, der hat in seiner vorherigen Firma nur mit Maßenverarbeitung von Daten zu tun gehabt, der hat mir diese möglichkeit empfohlen, welche sich meiner meinung nach auch anbietet, da kein schlüssel vorhanden ist, wenn man dann aber die tabelle sortiert und einen Binary search darüber legt, dürfte dass sehr viel performanz herausholen, ich selbst habe auch nicht gedacht, dass es so Performanter ist, aber bevor man ohne schlüssel eine DB abfragt ist es wesentlich schneller.
Naja ich würde sagen versuch macht klug

Re: Select auf 2 große Tabellen

Beitrag von ann_bine (ForumUser / 5 / 0 / 1 ) »
Mmmh - also die komplette Tabelle einlesen, habe ich schon probiert, führte aber zu einem Fehler, weil die interne Tabelle übergelaufen ist. Vielleicht hätte ich noch irgendetwas beachten müssen, damit eine interne Tabelle 30 Millionen Datensätze aufnehmen kann.

Hintergrundverarbeitung wäre eine prima Lösung, da der Report dann auch ein paar Stunden durchrödeln kann, allerdings kann der Fachbereich sich damit nicht anfreunden.

Deshalb habe ich nun doch eine Lösung mit 3 Joins, jeweils einer auf ein GSFNR-Feld, umgesetzt. Das läuft auch nicht gerade wie der Blitz, aber die Lösung ist besser als das, was ich vorher hatte. Der Fachbereich ist jetzt gerade am Testen und ich hoffe, dass die Laufzeit dabie insgesamt akzeptabel ausfällt.

:D Vielen, vielen Dank für alle Vorschläge! :D

Seite 1 von 1

Vergleichbare Themen

3
Antw.
3154
Views
JCO und große Tabellen
von Gast » 17.05.2005 16:00 • Verfasst in Java & SAP®
2
Antw.
2417
Views
SELECT über 6 DB-Tabellen
von Mavrix » 14.06.2007 07:48 • Verfasst in ABAP® für Anfänger
7
Antw.
8564
Views
Select auf zwei Tabellen
von mip » 27.03.2008 16:05 • Verfasst in ABAP® für Anfänger
9
Antw.
4244
Views
Select über 3 Tabellen
von Papst BenR » 08.09.2014 21:36 • Verfasst in ABAP® für Anfänger
6
Antw.
3385
Views
select mehrere tabellen
von thr-hn » 04.04.2014 13:39 • Verfasst in ABAP® für Anfänger

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 2 Tagen von Bright4.5 1 / 591
aRFC im OO-Kontext
vor 4 Wochen von ralf.wenzel 1 / 2219
Hilfe bei SWEC/SWE2
letzen Monat von retsch 1 / 8814