BTP

HANA Cursor 금지 — Set 전환 3가지 이유 #shorts #SAP #HANA

▶ YouTube에서 보기

Cursor가 HANA에서 느린 이유

커서는 본질적으로 OLTP의 행 지향 사고방식입니다. HANA의 SQLScript Optimizer는 절차형 루프를 만나는 순간 식별 가능한 세트 연산이 끊어지면서 plan vectorization이 깨집니다. 결과적으로 컬럼 스토어의 SIMD 처리, 파티션 병렬화, 조인 엔진의 hash/range 최적화를 거의 활용하지 못하고, 메인 스레드에서 직렬로 도는 모양새가 됩니다.

  • 매 FETCH마다 결과 패키징 오버헤드 발생
  • 중간 변수 할당으로 인해 옵티마이저의 식별/푸시다운 실패
  • 병렬 실행 단위(JE/CE) 비활성, 단일 스레드 처리
  • 대용량에서 트랜잭션 로그 및 락 점유 시간 증가

직접 해보기

안티패턴: Cursor 처리

예를 들어 매출 테이블에서 할인 등급별로 보너스를 갱신하는 시나리오를 봅니다. 커서로 풀면 익숙하지만 HANA에선 비효율입니다.

-- 안티패턴: 행 단위 커서 처리
DO BEGIN
  DECLARE CURSOR c_sales FOR
    SELECT order_id, amount FROM sales WHERE status = 'OPEN';
  FOR row AS c_sales DO
    IF :row.amount >= 10000 THEN
      UPDATE sales SET bonus = :row.amount * 0.05
       WHERE order_id = :row.order_id;
    ELSE
      UPDATE sales SET bonus = :row.amount * 0.01
       WHERE order_id = :row.order_id;
    END IF;
  END FOR;
END;

권장: Set 기반 처리

같은 로직을 단일 SET 연산으로 바꾸면 옵티마이저가 컬럼 스캔 한 번에 처리합니다.

-- 권장: Set-based 단일 UPDATE
UPDATE sales
   SET bonus = CASE
                 WHEN amount >= 10000 THEN amount * 0.05
                 ELSE amount * 0.01
               END
 WHERE status = 'OPEN';

성능 비교

실제 벤치마크에서는 수십만 건 기준 커서 대비 10~100배 수준의 응답 시간 단축이 보고되는 경우가 일반적입니다. 복잡한 분기 로직이라면 MERGE INTO나 테이블 변수(TABLE 타입) 기반 일괄 처리도 권장됩니다.

예외: Cursor를 써도 되는 경우

아주 작은 마스터 데이터의 순서 의존 처리, 외부 API 호출처럼 본질적으로 직렬일 때만 제한적으로 사용합니다. 대용량 트랜잭션·집계·갱신은 SET 기반 SQL, 또는 SQLScript의 테이블 변수 파이프라인으로 재작성하는 것이 일반적인 권장 패턴입니다.

핵심 한 줄

HANA에서 커서는 안티패턴, 한 줄씩 돌리지 말고 한 문장으로 처리하세요.

댓글 0

아직 댓글이 없습니다.