ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 대용량 itab 처리와 바이너리 직렬화/압축 정리
    SAP 2026. 7. 8. 19:05

    abap_itab_binary_guide.html
    0.02MB
    abap_itab_binary_guide.pdf
    0.11MB

     

     

    대용량 itab 처리와 바이너리 직렬화/압축 정리

    대용량 itab 처리와 바이너리 직렬화 / 압축 정리

    SAP ABAP에서 대용량 internal table을 다룰 때의 조회 최적화, 직렬화(EXPORT/IMPORT), 압축(CL_ABAP_GZIP), 그리고 xstring ↔ string 변환까지 실무 기준으로 정리한 내용입니다.

    1. 대용량 itab 처리 기본 원칙

    1-1) 데이터 조회 시 고려사항

    • SELECT * 지양, 필요한 필드만 지정 (메모리·네트워크 절감)
    • WHERE 조건이 인덱스 컬럼과 일치하는지 확인 (Full table scan 방지)
    • FOR ALL ENTRIES 사용 시: 빈 테이블 체크 필수, 중복 제거(SORT + DELETE ADJACENT DUPLICATES) 필요. 내부적으로 OR 조건으로 풀리므로 대량 데이터엔 JOIN이 더 유리한 경우가 많음
    • 가능하면 DB단(HANA)에서 필터링·집계 후 최소 결과만 가져오는 코드 푸시다운 방식 사용
    • 대용량은 SELECT ... PACKAGE SIZE n 커서 방식으로 청크 단위 처리

    1-2) 데이터 압축 가능 여부

    • itab 자체를 압축한 채로 "연산에 사용"하는 것은 불가능 — 압축 해제해야 처리 가능
    • 압축은 어디까지나 저장 / 전송용으로 활용
    💡 근본적으로는 ABAP 레이어에서 압축을 고민하기보다, 로직을 HANA로 내려서 애초에 전송/처리량 자체를 줄이는 것이 정석입니다.

    1-3) 데이터 핸들링 최적화

    • 접근 패턴에 맞는 테이블 타입 선택: 순차 접근은 STANDARD, 키 기반 단건 조회는 HASHED, 범위 조회+정렬은 SORTED
    • STANDARD 테이블도 SORTED/HASHED Secondary Key 추가로 조회 성능 확보 가능
    • READ TABLE은 키 정의된 테이블에서 자동 최적화, 안되면 BINARY SEARCH 명시
    • Work area 대신 FIELD-SYMBOL/REF TOLOOP AT ... ASSIGNING → 불필요한 복사 제거
    • 중첩 LOOP는 최대한 피하고 HASHED lookup 또는 Parallel Cursor 기법 사용
    • 집계는 COLLECT 활용
    • 다건 수정은 MODIFY itab FROM wa TRANSPORTING fields WHERE로 일괄 처리
    • 처리 끝난 대용량 itab은 FREE로 명시적 메모리 해제
    • 초대용량이면 병렬처리(aRFC/Parallel Processing Framework) 또는 HANA 푸시다운 구조 검토

    2. EXPORT/IMPORT를 이용한 직렬화 + 압축

    대용량 itab을 저장/전송용으로 압축할 때 실무에서 많이 쓰는 패턴입니다. EXPORT ... TO DATA BUFFER로 itab을 xstring 바이너리로 직렬화한 뒤, CL_ABAP_GZIP으로 압축해서 저장/전송하고, 필요할 때만 다시 풀어서 씁니다.

    ⚠️ 압축된 상태에서는 itab 연산(LOOP, READ, SORT 등)이 불가능합니다. 반드시 압축 해제 후에만 처리 가능하므로, "지금 당장 계산에 쓸 데이터"가 아니라 보관/전달용 데이터에만 적용합니다.

    2-1) 직렬화가 itab보다 공간에 유리한 이유

    구분itab (메모리 상)직렬화(xstring)
    행별 관리정보각 row마다 admin 오버헤드 존재없음 (연속 바이트스트림)
    정렬(alignment)필드 타입별 padding 발생 가능최소화된 packed 형태
    테이블 헤더별도 관리 구조 유지타입 메타정보만 최소 포함
    확장 시 여유공간동적 확장 시 slack 공간 존재 가능해당 없음

    itab은 런타임 조작 편의성을 위해 구조적 오버헤드를 감수하는 반면, 직렬화는 "값들의 압축된 나열"에 가까워 원래도 더 콤팩트합니다. 여기에 gzip 압축까지 더하면, 텍스트성/반복값이 많은 데이터(코드값, 상태값, 마스터데이터)일수록 압축 효율이 좋고, 랜덤성 높은 데이터(GUID 등)는 효과가 적습니다.

    3. TO DATA BUFFER vs TO MEMORY

    구분EXPORT TO DATA BUFFEREXPORT TO MEMORY
    저장 위치지정한 xstring 변수 자체ABAP Memory (세션 내 공유 영역, ID 기반)
    결과물개발자가 직접 다루는 xstring 값시스템이 내부 관리, 직접 xstring으로 못 받음
    생존 범위변수가 살아있는 동안같은 세션(로그온) 내에서만
    외부 전송가능 (RFC, DB, 파일)불가 (세션 내부용)
    여러 AS 환경안전 (그냥 변수값)병렬처리/백그라운드job/RFC 시 실패 가능
    용도전송/저장/직렬화같은 세션 내 프로그램 간 전달
    ⚠️ TO MEMORY는 병렬처리(aRFC), 백그라운드 job, RFC 호출 등으로 work process/AS가 분리되면 memory ID를 못 찾아 IMPORT가 실패할 수 있습니다. 전송이 목적이라면 DATA BUFFER만 사용하는 것이 안전합니다.

    3-1) 소스코드 - TO DATA BUFFER (전송/저장용)

    DATA: lt_itab       TYPE STANDARD TABLE OF ty_large_line,
          lv_xstring    TYPE xstring,
          lv_compressed TYPE xstring.
    
    " itab -> xstring 직렬화
    EXPORT itab = lt_itab TO DATA BUFFER lv_xstring.
    
    " 압축 (선택)
    CALL METHOD cl_abap_gzip=>compress_binary
      EXPORTING
        raw_in   = lv_xstring
      IMPORTING
        gzip_out = lv_compressed.
    
    " ... lv_compressed 를 RFC/DB/파일로 전송 ...
    
    " 복원
    DATA: lv_decompressed  TYPE xstring,
          lt_itab_restored TYPE STANDARD TABLE OF ty_large_line.
    
    CALL METHOD cl_abap_gzip=>decompress_binary
      EXPORTING
        gzip_in = lv_compressed
      IMPORTING
        raw_out = lv_decompressed.
    
    IMPORT itab = lt_itab_restored FROM DATA BUFFER lv_decompressed.

    3-2) 소스코드 - TO MEMORY (같은 세션 내 프로그램 간 전달용)

    " ---- 호출 프로그램 (데이터를 전달하는 쪽) ----
    DATA: lt_itab TYPE STANDARD TABLE OF ty_large_line.
    
    EXPORT itab = lt_itab TO MEMORY ID 'ZMY_DATA'.
    
    SUBMIT zsub_report.
    " 또는: CALL TRANSACTION 'ZXXX'.
    
    " ---- 호출된 프로그램 (데이터를 받는 쪽) ----
    DATA: lt_itab2 TYPE STANDARD TABLE OF ty_large_line.
    
    IMPORT itab = lt_itab2 FROM MEMORY ID 'ZMY_DATA'.
    
    " 사용 후 반드시 명시적 해제 (안 하면 세션 종료까지 잔류)
    FREE MEMORY ID 'ZMY_DATA'.

    3-3) 소스코드 - 다중 변수 EXPORT/IMPORT

    DATA: lt_header TYPE STANDARD TABLE OF ty_header,
          lt_item   TYPE STANDARD TABLE OF ty_item,
          lv_meta   TYPE string.
    
    EXPORT header = lt_header
           item   = lt_item
           meta   = lv_meta
           TO DATA BUFFER lv_xstring.
    
    IMPORT header = lt_header
           item   = lt_item
           meta   = lv_meta
           FROM DATA BUFFER lv_xstring.

    4. 버퍼 / 메모리 용량 한계

    • xstring 이론적 한계: 약 2GB (길이 필드가 4바이트 정수 기반)
    • 실질적 제약은 세션의 Roll Area / Extended Memory / Heap Memory 파라미터
    • 수십MB급: 문제없음
    • 수백MB급: 압축 필수 고려, 메모리 파라미터 확인 필요
    • GB급 이상: itab 통째 로딩 방식 재검토 → PACKAGE 분할 처리 또는 HANA 푸시다운 구조로 전환

    ST02(버퍼/메모리 현황), SM04(세션별 메모리 사용량) 트랜잭션으로 실제 운영 시스템의 여유치를 확인하는 것이 가장 정확합니다.

    5. CL_ABAP_GZIP

    메소드용도
    compress_binaryxstring(바이너리) → 압축
    decompress_binary압축된 xstring → 원본 바이너리 복원
    compress_textstring(텍스트) → 압축 (코드페이지 고려)
    decompress_text압축된 데이터 → 원본 텍스트 복원

    5-1) 바이너리 압축/해제

    DATA: lv_raw          TYPE xstring,
          lv_compressed   TYPE xstring,
          lv_decompressed TYPE xstring.
    
    EXPORT itab = lt_itab TO DATA BUFFER lv_raw.
    
    CALL METHOD cl_abap_gzip=>compress_binary
      EXPORTING
        raw_in         = lv_raw
    *   compress_level = 6        " 0(무압축,빠름) ~ 9(최고압축,느림), 기본값 6
      IMPORTING
        gzip_out       = lv_compressed.
    
    " ... lv_compressed 를 RFC로 전송하거나 DB/파일에 저장 ...
    
    CALL METHOD cl_abap_gzip=>decompress_binary
      EXPORTING
        gzip_in  = lv_compressed
      IMPORTING
        raw_out  = lv_decompressed.
    
    IMPORT itab = lt_itab FROM DATA BUFFER lv_decompressed.

    5-2) 텍스트 압축

    DATA: lv_text         TYPE string,
          lv_compressed   TYPE xstring,
          lv_decompressed TYPE string.
    
    CALL METHOD cl_abap_gzip=>compress_text
      EXPORTING
        text_in  = lv_text
      IMPORTING
        gzip_out = lv_compressed.
    
    CALL METHOD cl_abap_gzip=>decompress_text
      EXPORTING
        gzip_in  = lv_compressed
      IMPORTING
        text_out = lv_decompressed.
    ⚠️ 자체 예외 처리가 없는 편이라 입력값이 비어있는지(XSTRLEN( lv_raw ) = 0) 사전 체크가 필요하고, 압축 안 된 데이터를 decompress_binary에 넣으면 런타임 에러가 발생할 수 있습니다. 압축 여부를 별도 플래그/헤더로 관리하는 것을 권장합니다.

    5-3) 압축 효과 실측 팁

    DATA(lv_before) = xstrlen( lv_raw ).
    DATA(lv_after)  = xstrlen( lv_compressed ).
    DATA(lv_ratio)  = ( lv_after * 100 ) / lv_before.
    " lv_ratio가 100에 가까우면 압축 효과 미미 -> 압축 스킵 로직 고려

    6. xstring ↔ string 변환

    ⚠️ 핵심 구분: 원본이 실제 UTF-8 텍스트면 codepage 변환 함수를 사용하고, 압축 데이터나 이미지 같은 임의 바이너리는 반드시 Base64/HEX 인코딩을 사용해야 합니다. 임의 바이너리에 codepage 변환 함수를 쓰면 예외 발생 또는 데이터 손상 위험이 있습니다.

    6-1) xstring → string (진짜 텍스트 데이터일 때만)

    DATA: lv_xstring TYPE xstring,
          lv_string  TYPE string.
    
    TRY.
        lv_string = cl_abap_codepage=>convert_from(
                      input    = lv_xstring
                      encoding = 'UTF-8' ).   " encoding 생략 가능 (시스템 기본값 사용)
      CATCH cx_parameter_invalid_range
            cx_sy_codepage_converter_init
            cx_sy_conversion_codepage INTO DATA(lx_error).
        " 변환 실패 처리
        DATA(lv_msg) = lx_error->get_text( ).
    ENDTRY.

    6-2) string → xstring (역방향)

    DATA: lv_string  TYPE string,
          lv_xstring TYPE xstring.
    
    TRY.
        lv_xstring = cl_abap_codepage=>convert_to(
                       input    = lv_string
                       encoding = 'UTF-8' ).
      CATCH cx_parameter_invalid_range
            cx_sy_codepage_converter_init
            cx_sy_conversion_codepage INTO DATA(lx_error).
        " 변환 실패 처리
    ENDTRY.

    6-3) 함수모듈 방식 (구버전 호환)

    " xstring -> string
    CALL FUNCTION 'SCMS_XSTRING_TO_STRING'
      EXPORTING
        buffer = lv_xstring
      IMPORTING
        text   = lv_string.
    
    " string -> xstring
    CALL FUNCTION 'SCMS_STRING_TO_XSTRING'
      EXPORTING
        text   = lv_string
      IMPORTING
        buffer = lv_xstring.

    6-4) 압축/임의 바이너리는 Base64로 (안전한 방법)

    DATA: lv_binary TYPE xstring,
          lv_base64 TYPE string.
    
    " xstring -> Base64 string (무손실, 텍스트로 안전하게 표현 가능)
    lv_base64 = cl_http_utility=>encode_x_base64( lv_binary ).
    
    " Base64 string -> xstring (원복)
    lv_binary = cl_http_utility=>decode_x_base64( lv_base64 ).

    체크리스트 요약

    • ☐ 대용량 조회는 필요 필드만 SELECT, 가능하면 HANA 푸시다운으로 결과만 가져오기
    • ☐ 접근 패턴에 맞는 itab 타입(STANDARD/SORTED/HASHED) 선택
    • ☐ 저장/전송 목적이면 EXPORT TO DATA BUFFER 사용 (TO MEMORY 아님)
    • ☐ 여러 AS/병렬처리/RFC 환경이면 TO MEMORY 절대 사용 금지
    • ☐ 압축 전/후 사이즈 비교로 실제 효과 확인 후 압축 여부 결정
    • ☐ 텍스트 변환은 원본이 진짜 텍스트인지 임의 바이너리인지 먼저 구분
    • ☐ 임의 바이너리/압축 데이터는 Base64 또는 HEX로만 문자열화
    #SAP #ABAP #itab최적화 #EXPORT_IMPORT #DATA_BUFFER #CL_ABAP_GZIP #xstring #대용량처리 #HANA
Designed by Tistory.