Ansicht
Dokumentation

ABENITAB_WHERE_OPTIMIZATION - ITAB WHERE OPTIMIZATION

ABENITAB_WHERE_OPTIMIZATION - ITAB WHERE OPTIMIZATION

CL_GUI_FRONTEND_SERVICES - Frontend Services   TXBHW - Original Tax Base Amount in Local Currency  
Diese Dokumentation steht unter dem Copyright der SAP AG.
SAP E-Book

- Optimierung der WHERE-Bedingung

Bei den Anweisungen LOOP AT, DELETE und MODIFY kann eine WHERE-Bedingung angegeben werden, um bestimmte Zeilen der internen Tabelle zu selektieren. Während die Suche über eine Standardtabelle bei Verwendung des primären Tabellenschlüssels immer linear ist und nicht optimiert werden kann, kann die Suche bei der Verwendung eines sortierten Schlüssels oder eines Hash-Schlüssel unter Umständen optimiert werden. Diese Schlüssel werden verwendet bei der:

Die Optimierung findet dadurch statt, dass alle relationalen Ausdrücke oder ein Teil der relationalen Ausdrücke der WHERE-Bedingung auf eine Schlüsselangabe abgebildet wird. Mit dieser Schlüsselangabe wird ein entsprechender optimierter Schlüsselzugriff (binäre Suche bzw. Hash-Algorithmus wie bei der Anweisung READ TABLE oder einem Tabellenausdruck) durchgeführt, um einzelne oder mehrere Zeilen zu finden. Die gefundene Zeile bzw. die gefundenen Zeilen werden danach mit den verbleibenden relationalen Ausdrücken der WHERE-Bedingung überprüft, die nicht auf die Schlüsselangabe abgebildet wurden.

Voraussetzung für die Optimierung ist also,

  • dass relationale Ausdrücke der WHERE-Bedingung in eine Schlüsselangabe umgeformt werden können und
  • dass der entsprechende Schlüsselzugriff die gleichen Ergebnisse liefert wie sie die Auswertung dieses Anteils des logischen Ausdrucks liefern würde. Dies ist nur für kompatible Datentypen garantiert, da bei inkompatiblen Datentypen
  • bei einem Schlüsselzugriff der Inhalt der angegebenen Datenobjekte vor der Auswertung in den Datentyp der Spalten konvertiert wird und

  • bei Auswertung eines Vergleichsausdrucks die Vergleichsregeln für inkompatible Datentypen gelten, bei denen es von allen beteiligten Datentypen abhängt, welcher Operand in welchen Vergleichstyp konvertiert wird.

Wenn es keine oder nicht genügend relationalen Ausdrücke gibt, um beide dieser Voraussetzungen zu erfüllen kann nicht optimiert werden und das Verhalten ist wie folgt:

  • Bei einem Zugriff auf eine sortierte Tabelle oder eine Hash-Tabelle über den primären Tabellenschlüssel werden wie bei einer Standardtabelle alle Zeilen der internen Tabelle überprüft.
  • Bei einem Zugriff über einen sekundären Tabellenschlüssel, d.h., wenn hinter USING KEY ein solcher angegeben ist, kommt es zu einem Syntaxfehler, einer Warnung von der Syntaxprüfung oder zu einer Ausnahme. Ein Zugriff über einen sekundären Tabellenschlüssel muss immer optimiert ausgeführt werden.

Die folgenden Abschnitte beschreiben genauer wann ein Zugriff optimiert werden kann.

Hinweis

Wenn die mit WHERE selektierten Zeilen nicht nur mit LOOP AT gelesen, sondern mit MODIFY oder DELETE modifiziert oder gelöscht werden, fallen außer für die Suche nach den Zeilen weitere Aktualisierungskosten an. Insbesondere ist beim Löschen von Zeilen aus Standardtabellen zu beachten, dass eine Suche über einen Sekundärschlüssel zwar die Selektion der zu löschenden Zeilen optimiert, nicht aber die für die Löschung notwendige Aktualisierung des Primärschlüssels, welche in der Regel über eine lineare Suche erfolgt.

Voraussetzungen für die Optimierung bei Hash-Schlüsseln

Bei einem Zugriff über einen Hash-Schlüssel muss es für jede Komponente des Schlüssels genau einen mit AND kombinierten relationalen Ausdruck geben, der entweder ein Dieser Ausdruck ist entweder ein

  • Vergleichsausdruck mit dem Vergleichsoperator = (oder EQ), dessen Operanden die obenstehenden Anforderungen erfüllen, oder ein

Diese relationalen Ausdrücke bilden den für den Schlüsselzugriff verwendeten Anteil des logischen Ausdrucks. Dieser darf keine duplikativen Angaben von Schlüsselkomponenten enthalten. Der restliche logische Ausdruck darf beliebige weitere mit AND kombinierte relationale Ausdrücke enthalten. Wenn aber die Booleschen Operatoren NOT oder OR verwendet werden, kann unter Umständen nicht optimiert werden. In den nicht für den Schlüsselzugriff verwendeten relationalen Ausdrücken können auch Schlüsselkomponenten vorkommen.

Hinweis

Andere relationale Ausdrücke als Vergleiche mit = (oder EQ) oder Prädikatausdrücke IS INITIAL tragen nicht zum Schlüsselzugriff bei. Dies gilt insbesondere auch für den tabellarischen Vergleichsoperator IN range_tab, auch wenn er auf optimierbare Vergleiche zurück geführt werden könnte.

Beispiel

Im folgenden Beispiel sind die ersten beiden WHERE-Bedingungen als Schlüsselzugriffe mit dem sekundären Tabellenschlüssel key optimierbar, weil

  1. Die optimierbaren Bedingungen für b, d und e den gesamten Schlüssel abdecken,
  2. Die optimierbaren Bedingungen b, d und e den gesamten Schlüssel abdecken und a eine Bedingung auf eine Nichtschlüsselspalte ist, die nicht in den zur Optimierung notwendigen Teil der WHERE-Bedingung eingeht.
  3. Die optimierbaren Bedingungen b, d und e den gesamten Schlüssel abdecken und die anderen beiden Bedingungen auf die Schlüsselspalten b und d nicht optimierbar sind und deshalb nicht in den zur Optimierung notwendigen Teil der WHERE-Bedingung eingehen.

Die nächsten sechs WHERE-Bedingungen sind nicht optimierbar und führen zu Syntaxfehlern, weil

  1. die Schlüsselkomponente d nicht angegeben ist,
  2. eine Kombinierung einer Schlüsselkomponente mit OR statt mit AND geschieht,
  3. zwei nicht optimierbare relationale Operatoren verwendet werden,
  4. im Vergleich für b vom Typ c ein Operand vom Typ i angegeben ist, was nicht den Anforderungen an die Operanden genügt.
  5. der Boolesche Operator NOT vor einer Schlüsselkomponente vorkommt,
  6. eine weiterer Vergleich mit OR kombiniert wird,
  7. eine weiterer Vergleich mit NOT negiert wird.
DATA: BEGIN OF line,
        a TYPE c LENGTH 3,
        b    TYPE c LENGTH 3,
        c TYPE c LENGTH 3,
        d TYPE c LENGTH 3,
        e TYPE c LENGTH 3,
        f TYPE c LENGTH 3,
      END OF line.

DATA itab LIKE STANDARD TABLE OF line
               WITH UNIQUE HASHED KEY key COMPONENTS b e d.

DATA b_tab LIKE RANGE OF line-b.

LOOP AT itab INTO line USING KEY key
     WHERE b = '...' AND d = '...' AND e IS INITIAL.
ENDLOOP.

LOOP AT itab INTO line USING KEY key
     WHERE a = '...' AND b = '...' AND d = '...' AND e IS INITIAL.
ENDLOOP.

LOOP AT itab INTO line USING KEY key
     WHERE  b = '...' AND d = '...' AND e IS INITIAL AND
            b IN b_tab AND d <> '...'.
ENDLOOP.

LOOP AT itab INTO line USING KEY key
     WHERE b = '...' AND e IS INITIAL.                     "syntax error
ENDLOOP.

LOOP AT itab INTO line USING KEY key
     WHERE b = '...' OR d = '...' AND e IS INITIAL OR      "syntax error
ENDLOOP.

LOOP AT itab INTO line USING KEY key
     WHERE b = '...' AND d <> '...' AND e IS NOT INITIAL.  "syntax error
ENDLOOP.

LOOP AT itab INTO line USING KEY key
     WHERE b = 333 AND d = '...' AND e IS INITIAL.         "syntax error
ENDLOOP.

LOOP AT itab INTO line USING KEY key
     WHERE b = '...'  AND NOT d = '...' AND e IS INITIAL.  "syntax error
ENDLOOP.

LOOP AT itab INTO line USING KEY key
     WHERE b = '...' AND d = '...' AND e IS INITIAL OR     "syntax error
           a = '...'.
ENDLOOP.

LOOP AT itab INTO line USING KEY key
     WHERE b = '...' AND d = '...' AND e IS INITIAL AND    "syntax error
           NOT a = '...'.
ENDLOOP.

Voraussetzungen für die Optimierung bei sortierten Schlüsseln

Für einen Zugriff über einen sortierten Schlüssel gilt das Gleiche wie bei einem Hash-Schlüssel, mit dem Unterschied, dass nicht der gesamte Schlüssel, sondern nur ein aus mindestens einer Komponente bestehendes Anfangsstück des Schlüssels abgedeckt werden muss.

Auf die interne Tabelle wird teilweise sequentiell zugegriffen. Der Aufsatzpunkt für die Bearbeitung wird durch eine Binärsuche mit den Teilbedingungen, die den Tabellenschlüssel teilweise oder ganz abdecken, bestimmt. Vom Aufsatzpunkt ab wird die Tabelle nur so lange prozessiert wie diese Teilbedingungen erfüllt sind.

Beispiel

Im folgenden Beispiel sind die ersten fünf WHERE-Bedingungen als Schlüsselzugriffe mit dem sekundären Tabellenschlüssel key optimierbar, weil

  1. b ein Anfangsstück des Schlüssels ist,
  2. b ein Anfangsstück des Schlüssels ist und a eine unabhängige Bedingung ist,
  3. b und e ein Anfangsstück des Schlüssels sind,
  4. b, e und d ein Anfangsstück des Schlüssels sind und die Reihenfolge in der WHERE-Bedingung keine Rolle spielt,
  5. b ein Anfangsstück des Schlüssels ist und d in diesem Fall eine unabhängige Bedingung ist, obwohl zum Schlüssel gehörig.

Die nächsten fünf WHERE-Bedingungen sind nicht optimierbar und führen zu Syntaxfehlern, weil

  1. e kein Anfangsstück des Schlüssels ist,
  2. kein Vergleich auf Ungleichheit stattfindet.
  3. ein Vergleich in einer Ranges-Tabelle angegeben ist,
  4. der Boolesche Operator NOT vorkommt,
  5. eine zusätzliche OR-Verknüpfung vorkommt.
DATA: BEGIN OF line,
        a TYPE c LENGTH 3,
        b    TYPE c LENGTH 3,
        c TYPE c LENGTH 3,
        d TYPE c LENGTH 3,
        e TYPE c LENGTH 3,
        f TYPE c LENGTH 3,
      END OF line.

DATA itab LIKE STANDARD TABLE OF line
               WITH UNIQUE SORTED KEY key COMPONENTS b e d.

DATA b_tab LIKE RANGE OF line-b.

LOOP AT itab INTO line USING KEY key
             WHERE b = '...'.
ENDLOOP.

LOOP AT itab INTO line USING KEY key
             WHERE a = '...' AND b IS INITIAL.
ENDLOOP.

LOOP AT itab INTO line USING KEY key
             WHERE b = '...' AND e = '...'.
ENDLOOP.

LOOP AT itab INTO line USING KEY key
             WHERE b = '...' AND d IS INITIAL AND e = '...'.
ENDLOOP.

LOOP AT itab INTO line USING KEY key
             WHERE b = '...' AND d <> '...'.
ENDLOOP.

LOOP AT itab INTO line USING KEY key
             WHERE e = '...'.                    "syntax error
ENDLOOP.

LOOP AT itab INTO line USING KEY key
             WHERE b <> '...'.                   "syntax error
ENDLOOP.

LOOP AT itab INTO line USING KEY key
             WHERE b IN b_tab.                   "syntax error
ENDLOOP.

LOOP AT itab INTO line USING KEY key
             WHERE b = '...'  AND NOT e = '...'. "syntax error
ENDLOOP.

LOOP AT itab INTO line USING KEY key             "syntax error
             WHERE b = '...'  AND ( d = '...' OR e IS INITIAL ).
ENDLOOP.

Anforderungen an die Operanden

Der Teil des logischen Ausdrucks, der auf einen Schlüsselzugriff abgebildet werden kann, muss die gleichen Zeilen selektieren wie eine Anweisung READ TABLE bzw. ein entsprechender Tabellenausdruck, in der die entsprechenden Komponenten als Schlüssel angegeben sind.

  • In der WHERE-Bedingung gelten beim Vergleich inkompatibler Datenobjekte die Vergleichsregeln für inkompatible Datentypen, bei denen es von den beteiligten Datentypen abhängt, welcher Operand in welchen Vergleichstyp konvertiert wird.
  • Bei Verwendung der Zusätze WITH TABLE KEY und WITH KEY der Anweisung READ bzw. KEY in einem Tabellenausdruck wird dagegen immer der Inhalt der angegebenen Datenobjekte vor dem Vergleich in den Datentyp der Spalten konvertiert.

Wenn es dadurch zu unterschiedlichen Ergebnissen kommt, ist eine Optimierung nicht möglich. Wegen der Komplexität der Vergleichsregeln insbesondere für elementare Datentypen ist es nicht sinnvoll, einen detaillierten Satz von Regeln aufzustellen, wann genau der Vergleichstyp mit dem Datentyp des linken Operanden übereinstimmt. In aller Regel

  • sind nur vollständig kompatible Operanden optimierbar,
  • können in manchen Fällen auch elementare Operanden unterschiedlicher Datentypen optimiert werden, wenn die Wertebereiche oder Längen geeignet sind. Beispielsweise ist ein Vergleich einer Spalte vom Typ einer Gleitpunktzahl mit einem Operand vom Typ Integer möglich oder von einer Spalte vom c mit einem ebensolchen Operanden, wenn dessen Länge kleiner als die der Spalte ist.

Es wird deshalb grundsätzlich empfohlen, in der WHERE-Bedingung nur paarweise kompatible Operanden zu verwenden. Damit ist sichergestellt, dass das unterschiedliche Verhalten der WHERE-Bedingung und einer Schlüsselangabe keinen Einfluss auf das Ergebnis hat.

Beispiel

Das folgende Beispiel entspricht im Wesentlichen dem in Abschnitt WHERE log_exp in LOOP AT itab. Während dort ein Zugriff über den primären Tabellenschlüssel und stillschweigend keine Optimierung stattfindet, handelt es sich hier um einen Zugriff über einen sekundären Tabellenschlüssel, bei dem es zu einer Warnung von der Syntaxprüfung und bei der Programmausführung zu einer Ausnahme kommt. Ob die Ausnahme ausgelöst wird, hängt von der Anzahl der Zeilen in der internen Tabelle ab.

DATA text_short TYPE c LENGTH 2.
DATA text_long  TYPE c LENGTH 4.

DATA itab LIKE TABLE OF text_short
          WITH UNIQUE HASHED KEY key COMPONENTS table_line.

itab = VALUE #( ( 'AA' )
                ( 'BB' )
                ( 'CC' )
                ( 'DD' )
                ( 'EE' )
                ( 'FF' )
                ( 'GG' )
                ( 'HH' )
                ( 'II' )
                ( 'JJ' )
                ( 'KK' )
                ( 'LL' )
                ( 'MM' ) ).

text_short = 'AA'.
text_long  = 'AAXX'.

LOOP AT itab INTO text_short USING KEY key
             WHERE table_line = text_long.
ENDLOOP.
cl_demo_output=>write( |LOOP: { sy-subrc }| ).

"Statement
READ TABLE itab INTO text_short WITH TABLE KEY key
                                COMPONENTS table_line = text_long.
cl_demo_output=>write( |READ: { sy-subrc }| ).

"Expression
TRY.
    text_short = itab[ KEY key COMPONENTS table_line = text_long ].
  catch CX_SY_ITAB_LINE_NOT_FOUND.
    ...
ENDTRY.
cl_demo_output=>display( |Expression: { text_short }| ).






General Material Data   PERFORM Short Reference  
Diese Dokumentation steht unter dem Copyright der SAP AG.

Length: 23477 Date: 20240523 Time: 181952     sap01-206 ( 269 ms )