Working with Sorted and Hashed Tables

Objectives
After completing this lesson, you will be able to:

After completing this lesson, you will be able to:

  • Prepare the code examples
  • Work with sorted and hashed tables

Try It Out: Code Example Preparation

  1. Choose Ctrl + Shift + N to create a new ABAP Repository object.
  2. Type the word database into the filter field, mark the search result Database Table, and choose Continue.
  3. Assign the new object to the package that you are working with and enter the name ZS4D401_FLIGHTS. Enter a description for the table and choose Next.
  4. Assign the object to a transport request and choose Finish .
  5. Enter the following code between the curly braces:
    Code snippet
    
    key client : abap.clnt not null;
    key carrier_id : /dmo/carrier_id not null;
    key connection_id : /dmo/connection_id not null;
    key flight_date : /dmo/flight_date not null;
    @Semantics.amount.currencyCode : 'zs4d401_flights.currency_code'
    price : /dmo/flight_price;
    currency_code : /dmo/currency_code;
    plane_type_id : /dmo/plane_type_id;
    seats_max : /dmo/plane_seats_max;
    seats_occupied : /dmo/plane_seats_occupied;
    Expand
  6. Select Ctrl + F3 to activate the table.
  7. Create a new ABAP class called ZCL_FILL_ZS4D401_FLIGHTS.
  8. Enter the following code in the implementation of the main method:
    Code snippet
    
    DATA flights TYPE TABLE OF /dmo/flight.
    DATA insert_tab TYPE TABLE OF /dmo/flight.
    
    
    DELETE FROM ZS4D401_flights.
    
    
    SELECT FROM /dmo/flight FIELDS * ORDER BY carrier_Id, connection_id INTO TABLE @flights .
    
    
    LOOP AT flights INTO DATA(first_date).
    * Original table flights has 2 flights per connection. Only process the first
    IF sy-tabix MOD 2 = 0. CONTINUE. ENDIF.
    
    
    *Extend flight dates by 2000 days
    DO 2000 TIMES.
    APPEND first_date TO insert_tab.
    first_date-flight_date += 1.
    ENDDO.
    * ENDIF.
    ENDLOOP.
    
    
    * Read highest connection number for each flight
    SELECT FROM /dmo/flight AS main FIELDS carrier_Id, connection_id, flight_date, price, currency_code, plane_type_id
    WHERE connection_id = ( SELECT MAX( connection_id ) FROM /dmo/flight WHERE carrier_id = main~carrier_id )
    AND flight_Date = ( SELECT MIN( flight_date ) FROM /dmo/flight WHERE carrier_id = main~carrier_id AND connection_id = main~connection_id )
    GROUP BY carrier_id, connection_Id, flight_date, price, currency_code, plane_type_id
    ORDER BY carrier_id, connection_id
    INTO TABLE @DATA(max).
    
    
    *Add 50 new connection numbers and 2000 days of flights for each
    LOOP AT max INTO DATA(line).
    DO 50 TIMES.
    line-connection_id += 1.
    line-plane_type_id = SWITCH #( CONV i( line-connection_id ) MOD 2 WHEN 0 THEN 'A330' WHEN 1 THEN 'A350' ).
    
    
    
    
    first_date = CORRESPONDING #( line ).
    DATA(repetitions) = COND i( WHEN line-carrier_id = 'LH' AND line-connection_id = '0405' THEN 4000 ELSE 2000 ).
    DO repetitions TIMES.
    first_date-seats_max = 220.
    APPEND first_date TO insert_tab.
    first_date-flight_date += 1.
    ENDDO.
    ENDDO.
    ENDLOOP.
    
    
    
    
    SORT insert_tab BY carrier_Id connection_id flight_date.
    DELETE ADJACENT DUPLICATES FROM insert_tab COMPARING carrier_id connection_id flight_date.
    
    
    
    
    INSERT ZS4D401_flights FROM TABLE @insert_tab.
    out->write( |Generated { sy-dbcnt } rows in table ZS4D401_flights| ).
    
    
    Expand
  9. Select Ctrl + F3 to activate the class.
  10. Select F9 to run the class. The main method fills an extra database table that is required for the code snippets in the next two sections.

Sorted and Hashed Tables

Up until now, we have worked with standard internal tables. The data in a standard table is not held in a particular sort order. Consequently, when you read data from the table, the system must search the table sequentially until it finds the row or rows that you need. Depending on the size of the table, this can take some time.

You can optimize the performance of read accesses to internal tables using sorted or hashed tables.

In a sorted table, the contents of the table are always sorted according to the key fields in ascending order. When you insert a new record into the table, the system ensures that it is placed at the correct position. Since the data is always sorted, the system can retrieve records more efficiently than from a standard table (as long as you follow particular rules).

Hashed tables are managed using a special hash algorithm. This ensures that the system can retrieve records very quickly even if the table is extremely large. However, this performance gain only works in very particular cases.

Access to a Sorted Table

In this video, you will see how to access a sorted table.

When you declare a hashed table, you must define it with a unique key – duplicates are never allowed.

Watch the video to know how to access a hashed table.

When to use Standard, Sorted, and Hashed Tables

Select each option to learn more.

Comparative Runtimes of Standard, Sorted, and Hashed Tables

This figure compares the runtimes of standard, sorted, and hashed tables.

Filling Sorted and Hashed Tables

When you use a standard table, you can use the APPEND statement to add the contents of a work area to the end of the table. This is not possible with hashed tables, and leads to a syntax error.

Technically, you can use the APPEND statement to fill a sorted table. However, you risk causing a runtime error if the line that you try to append does not belong at the end of the table according to the sort area. This would happen in our example.

The way to fill a hashed table and to fill a sorted table safely is to use the INSERT statement. INSERT ensures that the new row is inserted at the correct position in the table.

Try It Out: Sorted And Hashed Tables

  1. Create a new class that implements the interface IF_OO_ADT_CLASSRUN.
  2. Copy the following code snippet to the implementation part of method if_oo_adt_classrun~main( ):
    Code snippet
    
    * Run this class using the ABAP Profiler to measure relative access times for standard, sorted, and hashed tables
    
    
    data(flights) = new lcl_flights( ).
    flights->access_standard( ).
    flights->access_sorted( ).
    flights->access_hashed( ).
    
    
    out->write( |Done| ).
    Expand
  3. Switch to the Local Types tab and copy the following code snippet into the editor:
    Code snippet
    
    CLASS lcl_flights DEFINITION.
    PUBLIC SECTION.
    METHODS constructor.
    METHODS access_standard.
    METHODS access_sorted.
    METHODS access_hashed.
    PRIVATE SECTION.
    
    
    DATA standard_table TYPE STANDARD TABLE OF zs4d401_flights WITH NON-UNIQUE KEY carrier_id connection_id flight_date.
    DATA sorted_table TYPE SORTED TABLE OF zs4d401_flights WITH NON-UNIQUE KEY carrier_id connection_id flight_date.
    DATA hashed_table TYPE HASHED TABLE OF zs4d401_flights WITH UNIQUE KEY carrier_id connection_id flight_date.
    
    
    DATA key_carrier_id TYPE /dmo/carrier_id.
    DATA key_connection_id TYPE /dmo/connection_id.
    DATA key_date TYPE /dmo/flight_date.
    METHODS set_line_to_read.
    
    
    ENDCLASS.
    
    
    CLASS lcl_flights IMPLEMENTATION.
    
    
    METHOD access_hashed.
    DATA(result) = hashed_table[ carrier_Id = me->key_carrier_id connection_Id = me->key_connection_id flight_date = me->key_date ].
    ENDMETHOD.
    
    
    METHOD access_sorted.
    DATA(result) = sorted_table[ carrier_Id = me->key_carrier_id connection_Id = me->key_connection_id flight_date = me->key_date ].
    ENDMETHOD.
    
    
    METHOD constructor.
    SELECT FROM zs4d401_flights FIELDS * INTO TABLE @standard_table.
    SELECT FROM zs4d401_flights FIELDS * INTO TABLE @sorted_table.
    SELECT FROM zs4d401_flights FIELDS * INTO TABLE @hashed_table.
    
    
    set_line_to_read( ).
    ENDMETHOD.
    
    
    METHOD access_standard.
    DATA(result) = standard_table[ carrier_Id = me->key_carrier_id connection_Id = me->key_connection_id flight_date = me->key_date ].
    ENDMETHOD.
    
    
    
    
    METHOD set_line_to_read.
    DATA(line) = standard_table[ CONV i( lines( standard_table ) * '0.65' ) ].
    me->key_carrier_id = line-carrier_Id.
    me->key_connection_Id = line-connection_id.
    me->key_date = line-flight_date.
    
    
    ENDMETHOD.
    
    
    ENDCLASS.
    Expand
  4. Select Ctrl + F3 to activate the class.
  5. Right-click in the Editor and choose Profile As ...ABAP Application (Console).
  6. In the Details, uncheck the checkbox SQL database access and choose Finish.
  7. Switch to the ABAP Profiler perspective and double-click on the trace item (you may need to refresh the display first) .
  8. Choose Hit List.
  9. Compare the runtimes of the methods access_standard( ), access_sorted( ), and access_hashed( ).

Log in to track your progress & complete quizzes