본문 바로가기

SAP/HANA DB

[HANA DB] Native SQL VS VIEW 성능 비교

빅데이터 프로그램 전문가 과정 마지막 시간으로 HANA DB에 접근해서 레포트 정보를 추출하는 ABAP 프로그램을 작성해보았다.

 제목 : ABAP for SAP HANA 프로젝트
프로그램명 : ZHA400_01_PROJECT_1
유형 : 레포트
내용 : 항공사 예약시스템 담당자가 Order 년도별로 항공사별로, 로컬 통화별로 전체적인 합계 금액을 볼 수 있는 Report 프로그램.

1) 조회 화면

조건 1 : 주문 년도를 검색조건으로 설정( 2년 전 ~ 현재 년 )

2) 결과 화면

 

3) ABAP 소스 (Native SQL 이용)

여기서 주의 깊게 볼 부분은 파란색 부분의 Native SQL 문장이다.

*&---------------------------------------------------------------------*
*& Report  ZHA400_01_PROJECT_1
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT  zha400_01_project_1.

TYPES :  BEGIN OF   ty_s_list,
                   carrid TYPE scarr-carrid,
                   carrname TYPE scarr-carrname,
                   year(4),
                   loccurkey TYPE sbook-loccurkey,
                   loccuram TYPE sbook-loccuram,
                 END OF  ty_s_list,
                 ty_t_list TYPE TABLE OF ty_s_list.

DATA: gs_list TYPE ty_s_list,
            gt_list LIKE TABLE OF gs_list.

SELECT-OPTIONS: so_year FOR gs_list-year NO-EXTENSION.

INITIALIZATION.
  so_year-sign = 'I'.
  so_year-option = 'BT'.
  so_year-high = sy-datum+0(4).
  so_year-low = so_year-high - 1.
  APPEND so_year.

START-OF-SELECTION.

  PERFORM get_data_solution
                      CHANGING gt_list .

  SORT gt_list BY carrid year loccurkey.
  WRITE:  0 'Year', 8 'Airline', 16 'Airline Name', 35 'Local Currency',
                  45 'Price Sum'.
  ULINE.
  LOOP AT gt_list INTO gs_list.
    WRITE:/  gs_list-year UNDER 'Year' , gs_list-carrid UNDER 'Airline',
                   gs_list-carrname UNDER 'Airline Name', gs_list-loccurkey UNDER 'Local Currency',
                   gs_list-loccuram UNDER 'Price Sum'.
    CLEAR gs_list.
  ENDLOOP.
*&---------------------------------------------------------------------*
*&      Form  GET_DATA_TEMPLATE
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      <--P_CT_CUSTOMERS  text
*----------------------------------------------------------------------*
FORM get_data_solution
            CHANGING ct_list TYPE ty_t_list.
* Declarations
*********************

* Types for target fields
*  TYPES: BEGIN OF lty_s_scarr,
*                      carrid TYPE scarr-carrid,
*                      carrname TYPE scarr-carrname,
*                 END OF lty_s_scarr.
*
*  TYPES: BEGIN OF lty_s_book,
*                     carrid TYPE sbook-carrid,
*                     order_date TYPE sbook-order_date,
*                     cancelled TYPE sbook-cancelled,
*                     loccurkey TYPE sbook-loccurkey,
*                     loccuram TYPE sbook-loccuram,
*                 END OF lty_s_book.
*
*  TYPES: BEGIN OF lty_s_book_count,
*                     carrid TYPE sbook-carrid,
*                     year(4),
*                     loccurkey TYPE sbook-loccurkey,
*                     loccuram TYPE sbook-loccuram,
*                 END OF lty_s_book_count.

* Work Area for Result
  DATA: ls_list LIKE LINE OF ct_list,
              lv_begda(10) TYPE c,
              lv_endda(10) TYPE c.
*
** Targets for Select
*  DATA: lt_scarr TYPE SORTED TABLE OF scarr
*                                     WITH NON-UNIQUE KEY carrid,
*              ls_scarr TYPE scarr,
*
*              lt_sbook TYPE SORTED TABLE OF lty_s_book
*                                     WITH NON-UNIQUE KEY carrid order_date,
*              ls_sbook TYPE lty_s_book,
*              lt_sbook_count TYPE  TABLE OF lty_s_book_count,
**                                     WITH NON-UNIQUE KEY agencynum carrid year,
*              ls_sbook_count TYPE lty_s_book_count,
*              ls_sbook_count_t TYPE lty_s_book_count,
*              lv_year(4),
*              lv_tabix TYPE sy-tabix,
*              lv_rate TYPE p DECIMALS 1.
*
** help variables
*  DATA lv_count TYPE i.

* Processing
*****************************
*************************************************
* NEW SAP HANA DB ADBC WITH NATIVE SQL
*************************************************
  DATA: lo_con TYPE REF TO cl_sql_connection,
        lo_sql TYPE REF TO cl_sql_statement,
        lo_result TYPE REF TO cl_sql_result_set,
        lv_sql TYPE string,
*        lt_customer TYPE TABLE OF scustom, "MODIFY 1"
        lr_data TYPE REF TO data,
        lr_root TYPE REF TO cx_root,
        lv_text TYPE string.

  CONCATENATE so_year-low '-01-01' INTO lv_begda.
  CONCATENATE so_year-high '-12-31' INTO lv_endda.

  CLEAR ct_list.

  TRY.
      lo_con = cl_sql_connection=>get_connection('HANA').

      CREATE OBJECT lo_sql
        EXPORTING
          con_ref = lo_con.

      "** MODIFY 2 **"
      lv_sql = | SELECT | &&
               |      C.CARRID, | &&
               |      C.CARRNAME, | &&
               |      YEAR(B.ORDER_DATE) AS YEAR, | &&
               |      B.LOCCURKEY, | &&
               |      SUM( B.LOCCURAM ) AS LOCCURAM | &&
               | FROM SCARR AS C | &&
               | INNER JOIN ZSBOOK1 AS B | &&
               |      ON C.MANDT = B.MANDT | &&
               |      AND C.CARRID = B.CARRID | &&
               | WHERE C.MANDT = { sy-mandt } | &&
               | AND B.ORDER_DATE BETWEEN '{ lv_begda }' AND '{ lv_endda }' | &&
               | AND B.CANCELLED = '{ space }' | &&
               | GROUP BY C.CARRID, C.CARRNAME, YEAR(B.ORDER_DATE), B.LOCCURKEY | &&
               || .

      lo_result = lo_sql->execute_query( lv_sql ).
      "** MODIFY 3 **"
      GET REFERENCE OF ct_list INTO lr_data.
      lo_result->set_param_table( lr_data ).
      lo_result->next_package( ).
      lo_result->close( ).
    CATCH cx_root INTO lr_root.
      lv_text = lr_root->get_text( ).
      MESSAGE lv_text TYPE 'E'.
  ENDTRY.

*************************************************
* ORIGINAL SAP OPENQUERY
*************************************************
*  SELECT  carrid carrname
*      FROM scarr
*        INTO CORRESPONDING FIELDS OF TABLE lt_scarr.
*
*  CONCATENATE so_year-low '-01-01' INTO lv_begda.
*  CONCATENATE so_year-high '-12-31' INTO lv_endda.
*
*  SELECT  carrid order_date cancelled loccuram loccurkey
*        FROM zsbook1
*          INTO CORRESPONDING FIELDS OF TABLE lt_sbook
*   WHERE cancelled <> 'X'
*         AND order_date BETWEEN lv_begda AND lv_endda.
*
*
*  LOOP AT lt_sbook INTO ls_sbook.
*    ls_sbook_count-carrid = ls_sbook-carrid.
*    ls_sbook_count-year = ls_sbook-order_date+0(4).
*    ls_sbook_count-loccurkey = ls_sbook-loccurkey.
*    ls_sbook_count-loccuram = ls_sbook-loccuram.
*    COLLECT ls_sbook_count INTO lt_sbook_count.
*    CLEAR: ls_sbook_count, ls_sbook.
*  ENDLOOP.
*
*  SORT lt_sbook_count BY  carrid year loccurkey.
*
*  LOOP AT lt_sbook_count INTO ls_sbook_count.
*
*    MOVE-CORRESPONDING ls_sbook_count TO ls_list.
*    CLEAR ls_scarr.
*    READ TABLE lt_scarr WITH KEY carrid = ls_list-carrid INTO ls_scarr.
*    ls_list-carrname = ls_scarr-carrname.
*
*    APPEND ls_list TO ct_list.
*
*    CLEAR: ls_sbook_count, ls_list..
*  ENDLOOP.
*************************************************

ENDFORM.                    " GET_DATA_TEMPLATE

 

이와 유사한 방법으로 VIEW 를 통한 조회 방법이 있다. 사전에 HANA Studio 를 이용하여 Modeling 툴 방식으로 "yha400.demo/CA_PROJECT_S1" 이라는 뷰가 만들어져 있다. 이것을 FROM 절로 넣어서 사용하는 방식이다.

4) ABAP 소스 (View 이용)

여기서도 주의 깊게 볼 부분은 파란색 부분의 View 를 이용한 SQL 문장이다.

 

 

*&---------------------------------------------------------------------*
*& Report  ZHA400_01_PROJECT_1
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT  zha400_01_project_1.

TYPES :  BEGIN OF   ty_s_list,
                   carrid TYPE scarr-carrid,
                   carrname TYPE scarr-carrname,
                   year(4),
                   loccurkey TYPE sbook-loccurkey,
                   loccuram TYPE sbook-loccuram,
                 END OF  ty_s_list,
                 ty_t_list TYPE TABLE OF ty_s_list.

DATA: gs_list TYPE ty_s_list,
            gt_list LIKE TABLE OF gs_list.

SELECT-OPTIONS: so_year FOR gs_list-year NO-EXTENSION.

INITIALIZATION.
  so_year-sign = 'I'.
  so_year-option = 'BT'.
  so_year-high = sy-datum+0(4).
  so_year-low = so_year-high - 1.
  APPEND so_year.

START-OF-SELECTION.

  PERFORM get_data_solution
                      CHANGING gt_list .

  SORT gt_list BY carrid year loccurkey.
  WRITE:  0 'Year', 8 'Airline', 16 'Airline Name', 35 'Local Currency',
                  45 'Price Sum'.
  ULINE.
  LOOP AT gt_list INTO gs_list.
    WRITE:/  gs_list-year UNDER 'Year' , gs_list-carrid UNDER 'Airline',
                   gs_list-carrname UNDER 'Airline Name', gs_list-loccurkey UNDER 'Local Currency',
                   gs_list-loccuram UNDER 'Price Sum'.
    CLEAR gs_list.
  ENDLOOP.
*&---------------------------------------------------------------------*
*&      Form  GET_DATA_TEMPLATE
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      <--P_CT_CUSTOMERS  text
*----------------------------------------------------------------------*
FORM get_data_solution
            CHANGING ct_list TYPE ty_t_list.
* Declarations
*********************

* Types for target fields
*  TYPES: BEGIN OF lty_s_scarr,
*                      carrid TYPE scarr-carrid,
*                      carrname TYPE scarr-carrname,
*                 END OF lty_s_scarr.
*
*  TYPES: BEGIN OF lty_s_book,
*                     carrid TYPE sbook-carrid,
*                     order_date TYPE sbook-order_date,
*                     cancelled TYPE sbook-cancelled,
*                     loccurkey TYPE sbook-loccurkey,
*                     loccuram TYPE sbook-loccuram,
*                 END OF lty_s_book.
*
*  TYPES: BEGIN OF lty_s_book_count,
*                     carrid TYPE sbook-carrid,
*                     year(4),
*                     loccurkey TYPE sbook-loccurkey,
*                     loccuram TYPE sbook-loccuram,
*                 END OF lty_s_book_count.

* Work Area for Result
  DATA: ls_list LIKE LINE OF ct_list,
              lv_begda(10) TYPE c,
              lv_endda(10) TYPE c.
*
** Targets for Select
*  DATA: lt_scarr TYPE SORTED TABLE OF scarr
*                                     WITH NON-UNIQUE KEY carrid,
*              ls_scarr TYPE scarr,
*
*              lt_sbook TYPE SORTED TABLE OF lty_s_book
*                                     WITH NON-UNIQUE KEY carrid order_date,
*              ls_sbook TYPE lty_s_book,
*              lt_sbook_count TYPE  TABLE OF lty_s_book_count,
**                                     WITH NON-UNIQUE KEY agencynum carrid year,
*              ls_sbook_count TYPE lty_s_book_count,
*              ls_sbook_count_t TYPE lty_s_book_count,
*              lv_year(4),
*              lv_tabix TYPE sy-tabix,
*              lv_rate TYPE p DECIMALS 1.
*
** help variables
*  DATA lv_count TYPE i.

* Processing
*****************************
*************************************************
* NEW SAP HANA DB ADBC WITH NATIVE SQL
*************************************************
  DATA: lo_con TYPE REF TO cl_sql_connection,
        lo_sql TYPE REF TO cl_sql_statement,
        lo_result TYPE REF TO cl_sql_result_set,
        lv_sql TYPE string,
*        lt_customer TYPE TABLE OF scustom, "MODIFY 1"
        lr_data TYPE REF TO data,
        lr_root TYPE REF TO cx_root,
        lv_text TYPE string.

  CONCATENATE so_year-low '-01-01' INTO lv_begda.
  CONCATENATE so_year-high '-12-31' INTO lv_endda.

  CLEAR ct_list.

  TRY.
      lo_con = cl_sql_connection=>get_connection('HANA').

      CREATE OBJECT lo_sql
        EXPORTING
          con_ref = lo_con.

      "** MODIFY 2 **"
       lv_sql SELECT | &&
                |      CARRID| &&
                |      CARRNAME| &&
                |      YEAR| &&
                |      LOCCURKEY| &&
                |      LOCCURAM | &&
                | FROM _SYS_BIC."yha400.demo/CA_PROJECT_S1" | &&
                | ('PLACEHOLDER' ('$$INPUT_BYEAR$$','{ so_year-low }')| &&
                |  'PLACEHOLDER' ('$$INPUT_EYEAR$$','{ so_year-high }')) | &&
                | WHERE MANDT { sy-mandt } | &&
                || .
 

      lo_result = lo_sql->execute_query( lv_sql ).
      "** MODIFY 3 **"
      GET REFERENCE OF ct_list INTO lr_data.
      lo_result->set_param_table( lr_data ).
      lo_result->next_package( ).
      lo_result->close( ).
    CATCH cx_root INTO lr_root.
      lv_text = lr_root->get_text( ).
      MESSAGE lv_text TYPE 'E'.
  ENDTRY.

*************************************************
* ORIGINAL SAP OPENQUERY
*************************************************
*  SELECT  carrid carrname
*      FROM scarr
*        INTO CORRESPONDING FIELDS OF TABLE lt_scarr.
*
*  CONCATENATE so_year-low '-01-01' INTO lv_begda.
*  CONCATENATE so_year-high '-12-31' INTO lv_endda.
*
*  SELECT  carrid order_date cancelled loccuram loccurkey
*        FROM zsbook1
*          INTO CORRESPONDING FIELDS OF TABLE lt_sbook
*   WHERE cancelled <> 'X'
*         AND order_date BETWEEN lv_begda AND lv_endda.
*
*
*  LOOP AT lt_sbook INTO ls_sbook.
*    ls_sbook_count-carrid = ls_sbook-carrid.
*    ls_sbook_count-year = ls_sbook-order_date+0(4).
*    ls_sbook_count-loccurkey = ls_sbook-loccurkey.
*    ls_sbook_count-loccuram = ls_sbook-loccuram.
*    COLLECT ls_sbook_count INTO lt_sbook_count.
*    CLEAR: ls_sbook_count, ls_sbook.
*  ENDLOOP.
*
*  SORT lt_sbook_count BY  carrid year loccurkey.
*
*  LOOP AT lt_sbook_count INTO ls_sbook_count.
*
*    MOVE-CORRESPONDING ls_sbook_count TO ls_list.
*    CLEAR ls_scarr.
*    READ TABLE lt_scarr WITH KEY carrid = ls_list-carrid INTO ls_scarr.
*    ls_list-carrname = ls_scarr-carrname.
*
*    APPEND ls_list TO ct_list.
*
*    CLEAR: ls_sbook_count, ls_list..
*  ENDLOOP.
*************************************************

ENDFORM.                    " GET_DATA_TEMPLATE

5) 성능측정

TCode "SAT" 로 두 프로그램을 실행 후 결과를 비교해보았다. "Times" 탭에 보면 수행시간이 나오는데 동일한 HANA DB에 요청했다고 믿기지 않을 정도로 성능차이가 발생했다. 그리고 컬럼수가 적기는 하나 Row 수가 1,000만 건이나 들어있는 데이터를 Group by 해서 나온 결과가 놀랍지 않을 수 없다.

 


<Native SQL 방식>

 


<View를 이용한 SQL 방식>