排序表和哈希表的使用

文章详细比较了ABAP开发中使用标准表、排序表和哈希表进行数据操作的效率,特别强调了在数据量大且需要查找时选择哈希表或排序表的重要性。
摘要由CSDN通过智能技术生成


在ABAP开发中, 标准表(Standard Table)能搞定绝大多数情况下的数据操作。当数据量累积到一定量级后,使用标准表明显感觉卡顿的时候,可以考虑使用 排序表(Sorted Table)或者 哈希表(Hashed Table)

一、排序表

排序表将内容按照NON-UNIQUE KEY字段升序排序。插入数据时,系统会自动将数据放在指定位置。因为数据已经排序的原因,系统通过二分法(Binary search)能快速地查找到数据。
*因为数据自动排序的缘故,对排序表插入数据时,要使用insert,避免使用append

二、哈希表

哈希表的原理是将数据的UNIQUE KEY字段通过算法生成哈希值,将这个唯一的哈希值保存在一块内存中,系统可以通过哈希值快速定位到数据。因为不需要遍历表,哈希表在处理海量数据时性能突出。
哈希表使用要求:

  • 需指定UNIQUE KEY字段。
  • 表中的数据不可重复,既不能存在两条数据的UNIQUE KEY字段值相同。

三、效率对比

1.声明表

声明数据库表

@EndUserText.label : 'KDLK Flights'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table zkdlk_flights {

  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 : 'zkdlk_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;

}

2.填充数据

/DMO/FLIGHT表中复制一部分数据,并生成新的数据,填充到zkdlk_flights表中。
创建一个类,在main方法中填入以下代码,运行。插入了642000条数据。

DATA FLIGHTS TYPE TABLE OF /DMO/FLIGHT.
DATA INSERT_TAB TYPE TABLE OF /DMO/FLIGHT.

DELETE FROM ZKDLK_FLIGHTS.

SELECT FROM /DMO/FLIGHT
FIELDS *
ORDER BY CARRIER_ID, CONNECTION_ID
INTO TABLE @FLIGHTS.

LOOP AT FLIGHTS INTO DATA(FIRST_DATE).
  IF SY-TABIX MOD 2 = 0.
    CONTINUE.
  ENDIF.

  DO 2000 TIMES.
    APPEND FIRST_DATE TO INSERT_TAB.
    FIRST_DATE-FLIGHT_DATE += 1.
  ENDDO.
ENDLOOP.

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).

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 ZKDLK_FLIGHTS FROM TABLE @INSERT_TAB.
OUT->WRITE( SY-DBCNT ).

在这里插入图片描述

3.读取数据

将准备好的数据分别用三种内表读取,并在内表中查找指定的数据。
创建类,在Local Types中填入以下代码。

CLASS LCL_FLIGHTS DEFINITION.
  		
  PUBLIC SECTION.
    METHODS CONSTRUCTOR.
    METHODS ACCESS_STANDARD.
    METHODS ACCESS_SORTED.
    METHODS ACCESS_HASHED.
  PROTECTED SECTION.
  PRIVATE SECTION.
    DATA STANDARD_TABLE TYPE STANDARD TABLE OF ZKDLK_FLIGHTS WITH NON-UNIQUE KEY CARRIER_ID CONNECTION_ID FLIGHT_DATE.
    DATA SORTED_TABLE TYPE SORTED TABLE OF ZKDLK_FLIGHTS WITH NON-UNIQUE KEY CARRIER_ID CONNECTION_ID FLIGHT_DATE.
    DATA HASHED_TABLE TYPE HASHED TABLE OF ZKDLK_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_FLIGHT_DATE TYPE /DMO/FLIGHT_DATE.

    METHODS SET_LINE_TO_READ.

ENDCLASS.

CLASS LCL_FLIGHTS IMPLEMENTATION.

  METHOD CONSTRUCTOR.
    SELECT FROM ZKDLK_FLIGHTS FIELDS * INTO TABLE @STANDARD_TABLE.
    SELECT FROM ZKDLK_FLIGHTS FIELDS * INTO TABLE @SORTED_TABLE.
    SELECT FROM ZKDLK_FLIGHTS FIELDS * INTO TABLE @HASHED_TABLE.
    SET_LINE_TO_READ( ).
  ENDMETHOD.

  METHOD SET_LINE_TO_READ.
    DATA(LINE) = STANDARD_TABLE[ CONV I( LINES( STANDARD_TABLE ) * '0.8' ) ].
    ME->KEY_CARRIER_ID = LINE-CARRIER_ID.
    ME->KEY_CONNECTION_ID = LINE-CONNECTION_ID.
    ME->KEY_FLIGHT_DATE = LINE-FLIGHT_DATE.
  ENDMETHOD.

  METHOD ACCESS_STANDARD.
    DATA(RESULT) = STANDARD_TABLE[ CARRIER_ID = ME->KEY_CARRIER_ID CONNECTION_ID = ME->KEY_CONNECTION_ID FLIGHT_DATE = ME->KEY_FLIGHT_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_FLIGHT_DATE ].
  ENDMETHOD.

  METHOD ACCESS_HASHED.
    DATA(RESULT) = HASHED_TABLE[ CARRIER_ID = ME->KEY_CARRIER_ID CONNECTION_ID = ME->KEY_CONNECTION_ID FLIGHT_DATE = ME->KEY_FLIGHT_DATE ].
  ENDMETHOD.

ENDCLASS.

在main中填入以下代码,激活,运行。

DATA(FLIGHTS) = NEW LCL_FLIGHTS( ).
FLIGHTS->ACCESS_STANDARD( ).
FLIGHTS->ACCESS_SORTED( ).
FLIGHTS->ACCESS_HASHED( ).

OUT->WRITE( 'Done' ).

4.结果对比

通过ABAP Traces查看三种方式的执行时间。
在这里插入图片描述


总结

三种表的使用情况:

  • 数据量小的时候,使用标准表即可。
  • 数据量大,并且存在查找相关操作时,考虑使用哈希表或排序表。

打完收工。

  • 12
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值