Internal Table 성능(Select into, Read, Loop where) 비교
Standard Table, Sorted Table, Hashed Table
SAP Internal Table에 대한 설명과 각 유형별 성능 비교 자료는 구글링을 하면 무수히 많이 나오며, Easy ABAP에도 상세시 설명이 되어 있습니다.
다만, 대부분의 사이트에서 Internal Table 성능 비교에 대해 Append와 Read Table에서만 얘기하고 있어서
문득 Select into와 Standard Table에서 다른 유형의 Move시 그리고 Loop where에서의 성능이 얼마나 차이가 나는지 궁금해서 테스트를 해봤습니다.
단, Binary Search가 아닌 Standard table의 Read가 느리다는건 다들 알고 있으므로 비교에서는 생략했습니다.
#1. Internal Table 성능 비교 (100만건 테이터 기준)
시뮬레이션을 많이 해본것은 아니다보니 절대적인 성능 비교표는 아닙니다, '이정도 차이가 나는구나~' 하고 참고만 해주세요.
1만건, 5만건 같이 비교적 적은 데이터로 테스트 했을때는 Select into시 각 유형별 차이가 별로 없었습니다.

#2. 나름의 결론
Unique Key, Non Unique Key 모두 사용할수 있고, 대부분의 상황에서 준수한 성능을 내는 Sorted Table이 저에게는 최고인듯 싶습니다.
#3. 테스트 소스코드
REPORT YTEMP_SANDBOX.
INCLUDE ZCM_PROGRESS.
TYPES: BEGIN OF T_ITAB,
KEY1(20) TYPE C,
END OF T_ITAB.
DATA: LT_ITAB1 TYPE STANDARD TABLE OF T_ITAB,
LS_ITAB1 LIKE LINE OF LT_ITAB1,
LT_ITAB2 TYPE SORTED TABLE OF T_ITAB WITH UNIQUE KEY KEY1,
LS_ITAB2 LIKE LINE OF LT_ITAB2,
LT_ITAB3 TYPE HASHED TABLE OF T_ITAB WITH UNIQUE KEY KEY1,
LS_ITAB3 LIKE LINE OF LT_ITAB3,
LT_TEMP TYPE STANDARD TABLE OF T_ITAB,
LS_TEMP LIKE LINE OF LT_TEMP,
LV_STRING TYPE STRING,
LV_KEY1 LIKE LS_ITAB1-KEY1,
LV_TABIX TYPE SY-TABIX.
DATA: LV_RINDEX TYPE DATATYPE-INTEGER4.
DATA: LV_RTIME TYPE I.
PARAMETERS P_COUNT LIKE G_PROGRESS_TOTAL OBLIGATORY DEFAULT 1000000.
START-OF-SELECTION.
CLEAR : LT_ITAB1[], LT_ITAB2[], LT_ITAB3[], LT_TEMP[].
PERFORM INITIAL_PROGRESS_VARIANT.
G_PROGRESS_TOTAL = P_COUNT.
DO G_PROGRESS_TOTAL TIMES.
CALL FUNCTION 'GENERAL_GET_RANDOM_STRING'
EXPORTING
NUMBER_CHARS = 5
IMPORTING
RANDOM_STRING = LV_STRING
.
MOVE: LV_STRING TO LS_TEMP-KEY1. CONDENSE LS_TEMP-KEY1.
LS_TEMP-KEY1 = LS_TEMP-KEY1 && SY-TABIX.
APPEND LS_TEMP TO LT_TEMP.
PERFORM SET_PROGRESS_WITH_PERCENT USING 'Gen random string'.
ENDDO.
PERFORM INITIAL_PROGRESS_VARIANT.
G_PROGRESS_TOTAL = 12.
* select into 시간 비교
DATA: LT_BKPF_T TYPE STANDARD TABLE OF BKPF,
LT_BKPF_S TYPE SORTED TABLE OF BKPF WITH UNIQUE KEY MANDT BUKRS GJAHR BELNR,
LT_BKPF_H TYPE HASHED TABLE OF BKPF WITH UNIQUE KEY MANDT BUKRS GJAHR BELNR.
"STANDARD TABLE
PERFORM SET_PROGRESS_WITH_STEP USING 'Select-into Time - Standard Table'.
GET RUN TIME FIELD LV_RTIME.
SELECT
BUKRS, GJAHR, BELNR
FROM BKPF
INTO CORRESPONDING FIELDS OF TABLE @LT_BKPF_T
UP TO @P_COUNT ROWS
BYPASSING BUFFER.
IF SY-SUBRC EQ 0.
SORT LT_BKPF_T BY BUKRS GJAHR BELNR.
ENDIF.
PERFORM DETERMINE_WRITE USING 'Standard Table Select-Into' LV_RTIME.
PERFORM SET_PROGRESS_WITH_STEP USING 'Select-into Time - Sorted Table'.
GET RUN TIME FIELD LV_RTIME.
SELECT
BUKRS, GJAHR, BELNR
FROM BKPF
INTO CORRESPONDING FIELDS OF TABLE @LT_BKPF_S
UP TO @P_COUNT ROWS
BYPASSING BUFFER.
PERFORM DETERMINE_WRITE USING 'Sorted Table Select-Into' LV_RTIME.
PERFORM SET_PROGRESS_WITH_STEP USING 'Select-into Time - Hashed Table'.
GET RUN TIME FIELD LV_RTIME.
SELECT
BUKRS, GJAHR, BELNR
FROM BKPF
INTO CORRESPONDING FIELDS OF TABLE @LT_BKPF_H
UP TO @P_COUNT ROWS
BYPASSING BUFFER.
PERFORM DETERMINE_WRITE USING 'Hashed Table Select-Into' LV_RTIME.
* APPEND 시간 비교
"STANDARD TABLE
PERFORM SET_PROGRESS_WITH_STEP USING 'Data Move Time - Standard Table'.
GET RUN TIME FIELD LV_RTIME.
LT_ITAB1 = CORRESPONDING #( LT_TEMP[] ).
SORT LT_ITAB1 BY KEY1.
PERFORM DETERMINE_WRITE USING 'Standard Table Data Move' LV_RTIME.
"SORTED TABLE
PERFORM SET_PROGRESS_WITH_STEP USING 'Data Move Time - Sorted Table'.
GET RUN TIME FIELD LV_RTIME.
LT_ITAB2 = CORRESPONDING #( LT_TEMP[] ).
PERFORM DETERMINE_WRITE USING 'Sorted Table Data Move' LV_RTIME.
"HASHED TABLE
PERFORM SET_PROGRESS_WITH_STEP USING 'Data Move Time - Hashed Table'.
GET RUN TIME FIELD LV_RTIME.
LT_ITAB3 = CORRESPONDING #( LT_TEMP[] ).
PERFORM DETERMINE_WRITE USING 'Hashed Table Data Move'
LV_RTIME.
* READ TABLE 성능 비교
DATA(LV_TLINE) = LINES( LT_TEMP ).
"STANDARD TABLE BINARY SEARCH
PERFORM SET_PROGRESS_WITH_STEP USING 'Read Time - Binary Search'.
GET RUN TIME FIELD LV_RTIME.
DO LV_TLINE TIMES.
CALL FUNCTION 'RANDOM_I4'
EXPORTING
RND_MIN = 1
RND_MAX = LV_TLINE
IMPORTING
RND_VALUE = LV_RINDEX
.
READ TABLE LT_TEMP INTO LS_TEMP INDEX LV_RINDEX.
IF SY-SUBRC EQ 0.
READ TABLE LT_ITAB1 INTO LS_ITAB1 WITH KEY KEY1 = LS_TEMP-KEY1 BINARY SEARCH.
ENDIF.
ENDDO.
PERFORM DETERMINE_WRITE USING 'Binary Search'
LV_RTIME.
"SORTED TABLE
PERFORM SET_PROGRESS_WITH_STEP USING 'Read Time - Sorted Search'.
GET RUN TIME FIELD LV_RTIME.
DO LV_TLINE TIMES.
CALL FUNCTION 'RANDOM_I4'
EXPORTING
RND_MIN = 1
RND_MAX = LV_TLINE
IMPORTING
RND_VALUE = LV_RINDEX
.
READ TABLE LT_TEMP INTO LS_TEMP INDEX LV_RINDEX.
IF SY-SUBRC EQ 0.
READ TABLE LT_ITAB2 INTO LS_ITAB2 WITH TABLE KEY KEY1 = LS_TEMP-KEY1.
ENDIF.
ENDDO.
PERFORM DETERMINE_WRITE USING 'Sorted Search'
LV_RTIME.
"HASHED TABLE
PERFORM SET_PROGRESS_WITH_STEP USING 'Read Time - Hashed Search'.
GET RUN TIME FIELD LV_RTIME.
DO LV_TLINE TIMES.
CALL FUNCTION 'RANDOM_I4'
EXPORTING
RND_MIN = 1
RND_MAX = LV_TLINE
IMPORTING
RND_VALUE = LV_RINDEX
.
READ TABLE LT_TEMP INTO LS_TEMP INDEX LV_RINDEX.
IF SY-SUBRC EQ 0.
READ TABLE LT_ITAB3 INTO LS_ITAB3 WITH TABLE KEY KEY1 = LS_TEMP-KEY1.
ENDIF.
ENDDO.
PERFORM DETERMINE_WRITE USING 'Hashed Search'
LV_RTIME.
* Loop 성능 비교
"STANDARD TABLE LOOP - 실행 시간이 너무 오래 걸려서 주석처리
* PERFORM SET_PROGRESS_WITH_STEP USING 'Loop Time - Standard'.
* GET RUN TIME FIELD LV_RTIME.
* DO LV_TLINE TIMES.
* CALL FUNCTION 'RANDOM_I4'
* EXPORTING
* RND_MIN = 1
* RND_MAX = LV_TLINE
* IMPORTING
* RND_VALUE = LV_RINDEX
* .
* READ TABLE LT_TEMP INTO LS_TEMP INDEX LV_RINDEX.
* IF SY-SUBRC EQ 0.
* LOOP AT LT_ITAB1 INTO LS_ITAB1 WHERE KEY1 EQ LS_TEMP-KEY1.
*
* ENDLOOP.
* ENDIF.
* ENDDO.
* PERFORM DETERMINE_WRITE USING 'Standard Loop'
* LV_RTIME.
"SORTED TABLE LOOP
PERFORM SET_PROGRESS_WITH_STEP USING 'Loop Time - Sorted'.
GET RUN TIME FIELD LV_RTIME.
DO LV_TLINE TIMES.
CALL FUNCTION 'RANDOM_I4'
EXPORTING
RND_MIN = 1
RND_MAX = LV_TLINE
IMPORTING
RND_VALUE = LV_RINDEX
.
READ TABLE LT_TEMP INTO LS_TEMP INDEX LV_RINDEX.
IF SY-SUBRC EQ 0.
LOOP AT LT_ITAB2 INTO LS_ITAB2 WHERE KEY1 EQ LS_TEMP-KEY1.
ENDLOOP.
ENDIF.
ENDDO.
PERFORM DETERMINE_WRITE USING 'Sorted Loop'
LV_RTIME.
"HASHED TABLE LOOP
PERFORM SET_PROGRESS_WITH_STEP USING 'Loop Time - Hashed'.
GET RUN TIME FIELD LV_RTIME.
DO LV_TLINE TIMES.
CALL FUNCTION 'RANDOM_I4'
EXPORTING
RND_MIN = 1
RND_MAX = LV_TLINE
IMPORTING
RND_VALUE = LV_RINDEX
.
READ TABLE LT_TEMP INTO LS_TEMP INDEX LV_RINDEX.
IF SY-SUBRC EQ 0.
LOOP AT LT_ITAB3 INTO LS_ITAB3 WHERE KEY1 EQ LS_TEMP-KEY1.
ENDLOOP.
ENDIF.
ENDDO.
PERFORM DETERMINE_WRITE USING 'Hashed Loop'
LV_RTIME.
*&---------------------------------------------------------------------*
*& Form DETERMINE_WRITE
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> P_
*& --> LV_SDATE
*& --> LV_STIME
*&---------------------------------------------------------------------*
FORM DETERMINE_WRITE USING PV_TEXT
PV_RTIME.
DATA: LV_RTIME TYPE I,
LV_FTIME TYPE I.
GET RUN TIME FIELD LV_RTIME.
LV_FTIME = LV_RTIME - PV_RTIME.
WRITE :/ PV_TEXT,' : ', LV_FTIME, 'MicroSecond'.
ENDFORM.
'ABAP > 개발Tip' 카테고리의 다른 글
[개발Tip] ALV Field catalog(필드 카탈로그) 만드는 3가지 방법 (0) | 2023.08.25 |
---|---|
[개발Tip] RESTful API 호출 2가지 방법(CL_HTTP_CLIENT, CL_REST_HTTP_CLIENT) (0) | 2023.06.28 |
[개발Tip] REPLACE의 REGEX (정규표현식)를 이용한 특수문자 제거 (0) | 2023.06.22 |
[개발Tip] 비동기 처리를 위한 백그라운드 작업 생성 (0) | 2023.06.22 |
[개발Tip] 필드의 Conversion Exit(내부값/화면표시값 변환) 찾는 방법 (0) | 2023.05.11 |
댓글