コードの分析およびテスト
データ型およびデータ型変換の正しい使用
文字項目の処理
ABAP SQL でのコードプッシュダウンの使用
内部テーブルのパフォーマンスの改善
権限チェックの実装
効果的なオブジェクト指向コードの設計
例外クラスの定義と処理
ABAP コードへの文書の追加

二次キーを使用した内部テーブルのパフォーマンスの改善

Objective

After completing this lesson, you will be able to 二次キーを使用した内部テーブルのパフォーマンスの改善

二次キー

このビデオでは、内部テーブルの読込とそのキーなしの違いについて説明します。

一次キーの一部ではない項目を使用した内部テーブルへのアクセスを高速化するために、内部テーブルの定義に 1 つまたは複数の二次キーを追加することができます。

図に示すように、内部テーブルの二次キーはソートまたはハッシュのいずれかです。内部テーブルの一次キーと同様に、ソートキーは一意でも非一意でもかまいませんが、ハッシュキーは常に一意である必要があります。

二次キーを使用して二次キーによって内部テーブルのパフォーマンスを改善する方法については、このビデオを視聴してください。

内部テーブルに非一意の二次キーがある場合、プログラムによってキーを使用してテーブルがアドレスされるまで、キーは登録されません。初回キーの登録には余分な実行時間が費やされるため、通常、最初の読込アクセスは、キーを使用しなかった場合よりも負荷が高くなります。ただし、キーが存在すると、後続の読込アクセスが非常に高速になります (二次キーなしでテーブルを読み込むよりもかなり高速です)。

テーブル内容を変更しても、索引は自動的に更新されず、二次キーを使用する読込アクセスがこれ以上あるかどうかが確認されます。最初の後続読込アクセスで、二次キーが更新されます。これはキーの作成ほど高価ではありませんが、更新コストは中程度です。

一意の二次キーには 2 つの目的があります。1 つ目はテーブルへのアクセスを高速化するため、2 つ目は、テーブル内のすべてのローのキーの組み合わせがユニークであることを確認することです。したがって、キーは常に最新の状態に維持され、一意でない二次キーとは異なる更新方針が使用される必要があります。

内部テーブルの内容を変更する操作 (内容の入力または変更) によって、索引の登録 (初回アクセス) または更新 (後続アクセス) が行われます。二次索引は常に最新であるため、読込アクセスは常に高速です。

試してみる: 二次キー

  1. インタフェース IF_OO_ADT_CLASSRUN を実装する新しいクラスを登録します。
  2. 以下のコードスニペットをメソッド if_oo_adt_classrun~main( ) の実装部分にコピーします。
    Code Snippet
    1234567891011121314
    data(object) = new lcl_flights( ). * object->read_primary( ). object->read_non_key( ). object->read_secondary_1( ). object->read_secondary_2( ). object->read_secondary_3( ). out->write( 'Done' ).
  3. Local Types タブに切り替えて、以下のコードスニペットをエディタにコピーします。
    Code Snippet
    1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
    CLASS lcl_flights DEFINITION. PUBLIC SECTION. METHODS constructor. METHODS read_primary. METHODS read_non_key. METHODS read_secondary_1. METHODS read_secondary_2. METHODS read_secondary_3. PRIVATE SECTION. DATA connections TYPE SORTED TABLE OF Zs4d401_flights WITH NON-UNIQUE KEY carrier_id connection_Id flight_date. DATA connections_sk TYPE SORTED TABLE OF Zs4d401_flights WITH NON-UNIQUE KEY carrier_id connection_id flight_date WITH NON-UNIQUE SORTED KEY k_plane COMPONENTS plane_type_id. ENDCLASS. CLASS lcl_flights IMPLEMENTATION. METHOD constructor. SELECT FROM Zs4d401_flights FIELDS * INTO TABLE @connections. SELECT FROM Zs4d401_flights FIELDS * INTO TABLE @connections_sk. ENDMETHOD. METHOD read_non_key. LOOP AT connections INTO DATA(connection) WHERE plane_type_id = '737-800'. ENDLOOP. ENDMETHOD. METHOD read_primary. DATA count TYPE i VALUE 1. LOOP AT connections INTO DATA(connection) WHERE carrier_id = 'LH' AND connection_id = '0405' . count += 1. ENDLOOP. ENDMETHOD. METHOD read_secondary_1. LOOP AT connections_sk INTO DATA(connection) USING KEY k_plane WHERE plane_type_id = '737-800'. ENDLOOP. ENDMETHOD. METHOD read_secondary_2. LOOP AT connections_sk INTO DATA(connection) USING KEY k_plane WHERE plane_type_id = '737-800'. ENDLOOP. ENDMETHOD. METHOD read_secondary_3. LOOP AT connections_sk INTO DATA(connection) USING KEY k_plane WHERE plane_type_id = '737-800'. ENDLOOP. ENDMETHOD. ENDCLASS.
  4. Ctrl + F3 キーを押して、クラスを有効化します。
  5. エディタを右クリックし、Profile As... を選択します。ABAP アプリケーション (コンソール)
  6. Details で、チェックボックス SQL database access のチェックを外し、Finish を選択します。
  7. ABAP プロファイラパースペクティブに切り替え、トレース項目をダブルクリックします (最初に表示をリフレッシュする必要がある場合があります)。
  8. 該当対象一覧を選択します。
  9. メソッド read_primary( )read_secondary_2( )read_secondary_1( )、および read_secondary_3( ) の実行時間を比較します。

二次キーの定義および使用

静的属性 flights_buffer へのアクセスをさらに改善する必要があります。キーが 1 つしかないソートテーブルの代わりに、追加のソート二次キーを持つハッシュテーブルとして定義し、carrier_id 項目のみが指定されている場合のアクセスを最適化します。

テンプレート:

  • /LRN/CL_S4D401_ITS_TABLE_KIND (グローバルクラス)

ソリューション:

  • /LRN/CL_S4D401_ITS_SEC_KEY (グローバルクラス)

タスク 1: テンプレートのコピー (オプション)

テンプレートクラス /LRN/CL_S4D401_ITS_TABLE_KIND をコピーします。前の演習問題を完了した場合は、このタスクをスキップし、クラス ZCL_##_SOLUTION の編集を続行することができます。

ステップ

  1. クラス /LRN/CL_S4D401_ITS_TABLE_KIND を各自のパッケージのクラスにコピーします (推奨名: ZCL_##_SOLUTION、## はグループ番号)。

    1. Project Explorer で、クラス /LRN/CL_S4D401_ITS_TABLE_KIND を右クリックしてコンテキストメニューを開きます。

    2. コンテキストメニューから Duplicate.... を選択します。

    3. Package 項目にパッケージの名称を入力します。Name 項目に、ZCL_##_SOLUTION (## はグループ番号) と入力します。

    4. Next を選択します。

    5. 移送依頼を確認し、Finish を選択します。

  2. コピーを有効化します。

    1. Ctrl + F3 を押してクラスを有効化します。

タスク 2: 定義: 二次キー

ローカルクラス LCL_PASSENGER_FLIGHTS で、flights_buffer 属性をハッシュテーブルに変換します。次に、carrier_id 項目のみが指定されている場合に、アクセスを最適化する二次キーを定義します。

ステップ

  1. ローカルクラス LCL_PASSENGER_FLIGHT の静的属性 flights_buffer の定義にナビゲートします。

    1. たとえば、アウトラインビューでノード LCL_PASSENGER_FLIGHT を展開し、FLIGHTS_BUFFER を選択します。

  2. flights_buffer 属性の定義を調整します。テーブルの種類を HASHED TABLE に設定し、一次キー定義を適宜調整します。

    1. コードを以下のように調整します。

      注記

      ハッシュテーブルのキーは一意である必要があることに注意してください。
      ABAP
      1234567
      * CLASS-DATA: flights_buffer * TYPE SORTED TABLE OF st_flights_buffer * WITH NON-UNIQUE KEY carrier_id connection_id flight_date. CLASS-DATA: flights_buffer TYPE HASHED TABLE OF st_flights_buffer WITH UNIQUE KEY carrier_id connection_id flight_date.
  3. キー項目 carrier_id を使用して二次キー (推奨名: sk_carrier) を定義します。

    1. コードを以下のように調整します。

      ABAP
      1234
      CLASS-DATA: flights_buffer TYPE HASHED TABLE OF st_flights_buffer WITH UNIQUE KEY carrier_id connection_id flight_date WITH NON-UNIQUE SORTED KEY sk_carrier COMPONENTS carrier_id.
  4. Problems ビューでエントリを分析します。

    1. エディタの下にある Problems ビューを分析します。

    2. 判定をダブルクリックして、対応するコードにアクセスします。

タスク 3: 二次キーを使用

carrier_id 項目のみが指定されているローカルクラス LCL_PASSENGER_FLIGHT の静的属性 flights_buffer へのアクセスを調整します。新しい二次キーがこれらのアクセスで使用されていることを確認してください。

ステップ

  1. 関数 line_exists の呼出にナビゲートします。命令で二次キーが使用されるようにします。

    1. コードを以下のように調整します。

      ABAP
      1234
      IF NOT line_exists( flights_buffer[ KEY sk_carrier COMPONENTS carrier_id = i_carrier_id ] ).

      注記

      COMPONENTS オプションはオプションであり、省略できます。ここでは説明のためにこれを使用します。
  2. テーブル理解にナビゲートし、二次キーが使用されていることを確認します。

    1. コードを以下のように調整します。

      ABAP
      12345678910
      r_result = VALUE #( FOR <flight> IN flights_buffer USING KEY sk_carrier WHERE ( carrier_id = i_carrier_id ) ( NEW lcl_passenger_flight( i_carrier_id = <flight>-carrier_id i_connection_id = <flight>-connection_id i_flight_date = <flight>-flight_date ) ) ).
  3. グローバルクラスをコンソールアプリとして有効化してテストします。

    1. Ctrl + F3 を押します。

    2. F9 を押します。