- Ctrl + Shift + N を選択して、新しい ABAP リポジトリオブジェクトを作成します。
- フィルタ項目に単語 database を入力し、検索結果 Database Table をマークして、Continue を選択します。
- 作業しているパッケージに新しいオブジェクトを割り当て、名称 ZS4D401_FLIGHTS を入力します。テーブルの説明を入力し、Next を選択します。
- オブジェクトを移送依頼に割り当て、Finish を選択します。
- 中括弧の間に以下のコードを入力します。 Code Snippet1234567891011key 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;
- Ctrl + F3 キーを押してテーブルを有効化します。
- ZCL_FILL_ZS4D401_FLIGHTS という名称の新規 ABAP クラスを登録します。
- main メソッドの実装に以下のコードを入力します。 Code Snippet123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566DATA 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| ).
- Ctrl + F3 キーを押して、クラスを有効化します。
- F9 を選択して、クラスを実行します。main メソッドは、次の 2 つのセクションのコードスニペットに必要な追加のデータベーステーブルに入力します。
ソートテーブルおよびハッシュテーブルの使用
Objective
試してみる: コード例の準備
ソート済およびハッシュ済テーブル
これまで、標準内部テーブルを使用していました。標準テーブルのデータは、特定のソート順序で保持されません。したがって、テーブルからデータを読み込む場合、必要な行が見つかるまで、テーブルを順次検索する必要があります。テーブルのサイズによっては、この処理に時間がかかる場合があります。
ソートテーブルまたはハッシュテーブルを使用した内部テーブルへの読込アクセスのパフォーマンスを最適化することができます。

ソートテーブルでは、テーブルの内容は常にキー項目に従って昇順でソートされます。テーブルに新しいレコードを挿入する場合は、システムによって正しい位置に配置されます。データは常にソートされているため、標準テーブルよりも効率的にレコードを取得することができます (特定のルールに従っている場合)。
ハッシュテーブルは、特別なハッシュアルゴリズムを使用して管理されます。これにより、テーブルが非常に大きな場合でもデータを迅速に取得することができます。ただし、このパフォーマンスの向上は、非常に特殊なケースでのみ機能します。
ソートテーブルへのアクセス
このビデオでは、ソートテーブルにアクセスする方法を学習します。

ハッシュテーブルを宣言するときは、ユニークキーを使用して定義してください。重複は許可されません。
ハッシュテーブルにアクセスする方法については、ビデオを視聴してください。
標準テーブル、ソートテーブル、ハッシュテーブルを使用する場合

内部テーブルにデータを書き込んでから、テーブル全体にループを実装する場合は、標準テーブルを使用することができます。ソートテーブルとハッシュテーブルのパフォーマンスの最適化は、ループにフィルタがないため関係ありません。

この例は、ソートテーブルとハッシュテーブルをいつ使用する必要があるかを示しています。これには、where 句の最初のキー項目を使用したテーブル接続に対するループが含まれます。これは、キーが完全には指定されていない場合でもバイナリ検索手法を使用できるため、ソートテーブルを使用する場合に該当します。
ループ内で、航空会社テーブルのエントリが検索されます。そのため、フルキーを使用してテーブルへのアクセスが繰り返されています。これは、ハッシュテーブルを使用する場合に最適です。
標準テーブル、ソートテーブル、およびハッシュテーブルの比較実行時間
この図は、標準テーブル、ソートテーブル、およびハッシュテーブルの実行時間を比較したものです。

ソートテーブルおよびハッシュテーブルの書込
標準テーブルを使用する場合は、APPEND 命令を使用して、作業領域の内容をテーブルの最後に追加することができます。これは、ハッシュテーブルでは実行できず、構文エラーが発生します。
技術的には、APPEND 命令を使用してソートテーブルにデータを書き込むことができます。ただし、追加しようとしている行がソート順序に従ってテーブルの最後に属していない場合は、実行時エラーが発生するリスクがあります。これは、この例では発生します。

ハッシュテーブルにデータを書き込み、ソートテーブルを安全に埋める方法は、INSERT 文を使用することです。INSERT は、新しいローがテーブル内の正しい位置に挿入されるようにします。
試してみる: ソート済およびハッシュ済テーブル
- インタフェース IF_OO_ADT_CLASSRUN を実装する新しいクラスを登録します。
- 以下のコードスニペットをメソッド if_oo_adt_classrun~main( ) の実装部分にコピーします。Code Snippet1234567891011* 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| ).
- Local Types タブに切り替えて、以下のコードスニペットをエディタにコピーします。 Code Snippet1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465CLASS 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.
- Ctrl + F3 キーを押して、クラスを有効化します。
- エディタを右クリックし、Profile As... を選択します。→ABAP アプリケーション (コンソール)
- Details で、チェックボックス SQL database access のチェックを外し、Finish を選択します。
- ABAP プロファイラパースペクティブに切り替え、トレース項目をダブルクリックします (最初に表示をリフレッシュする必要がある場合があります)。
- 該当対象一覧を選択します。
- メソッド access_standard( )、access_sorted( )、および access_hashed( ) の実行時間を比較します。
ソートテーブルおよびハッシュテーブルの使用
コードに、テーブルタイプが標準テーブルの大きな内部テーブルが含まれていることに気付きました。これらのテーブルへのアクセス方法をコードで分析し、キーによってのみアクセスされていることを検出します。パフォーマンスを改善するには、内部テーブルの定義を、アクセス方法に応じてソートテーブルまたはハッシュテーブルのいずれかに変更します。
テンプレート:
- /LRN/CL_S4D401_ITS_FSYM (グローバルクラス)
ソリューション:
- /LRN/CL_S4D401_ITS_TABLE_KIND (グローバルクラス)