상관 서브쿼리의 성능 문제
ABAP Open SQL에서 상관 서브쿼리(Correlated Subquery)는 외부 쿼리의 각 행마다 내부 쿼리를 반복 실행합니다. 결과 집합이 수만 건이라면 데이터베이스에 수만 번의 서브쿼리가 실행되어 성능이 급격히 나빠집니다. SAP HANA 2.0 SPS 04 이후부터 지원하는 LATERAL JOIN은 이 문제를 해결합니다.
상관 서브쿼리 예제 — 문제 상황
" 각 고객별 최근 주문 1건 조회 — 상관 서브쿼리 방식
SELECT cust.customer_id,
cust.customer_name,
( SELECT TOP 1 ord.order_date
FROM zbtp_sales_order AS ord
WHERE ord.customer_id = cust.customer_id
ORDER BY ord.order_date DESCENDING ) AS last_order_date
FROM zbtp_customer AS cust
INTO TABLE @DATA(lt_result).
이 쿼리는 zbtp_customer 테이블의 행 수만큼 zbtp_sales_order 서브쿼리가 실행됩니다. 고객이 10만 명이면 서브쿼리가 10만 번 실행됩니다.
LATERAL JOIN으로 동일 결과를 효율적으로
" LATERAL JOIN 방식 — HANA 2.0 SPS04+ 필요
SELECT cust.customer_id,
cust.customer_name,
last_ord.order_date AS last_order_date,
last_ord.order_amount
FROM zbtp_customer AS cust
CROSS JOIN LATERAL (
SELECT TOP 1 ord.order_date, ord.order_amount
FROM zbtp_sales_order AS ord
WHERE ord.customer_id = cust.customer_id
ORDER BY ord.order_date DESCENDING
) AS last_ord
INTO TABLE @DATA(lt_result).
LATERAL JOIN은 외부 쿼리의 컬럼을 참조하는 서브쿼리를 JOIN처럼 사용합니다. HANA 옵티마이저가 전체 쿼리를 한 번의 실행 계획으로 최적화하므로 상관 서브쿼리보다 훨씬 빠릅니다.
LEFT OUTER JOIN LATERAL — 데이터 없는 고객 포함
주문이 없는 고객도 결과에 포함시키려면 LEFT OUTER JOIN LATERAL을 사용합니다.
SELECT cust.customer_id,
cust.customer_name,
last_ord.order_date AS last_order_date,
last_ord.order_amount AS last_order_amount
FROM zbtp_customer AS cust
LEFT OUTER JOIN LATERAL (
SELECT TOP 1 ord.order_date, ord.order_amount
FROM zbtp_sales_order AS ord
WHERE ord.customer_id = cust.customer_id
ORDER BY ord.order_date DESCENDING
) AS last_ord ON 1 = 1
INTO TABLE @DATA(lt_result).
주문이 없는 고객의 경우 last_order_date와 last_order_amount는 초기값(공백/0)으로 채워집니다.
LATERAL JOIN으로 집계값 가져오기
각 부서별 직원 수와 평균 급여를 구하면서 부서 정보도 함께 조회하는 경우:
SELECT dept.department_id,
dept.department_name,
dept.budget,
stats.headcount,
stats.avg_salary
FROM zbtp_department AS dept
CROSS JOIN LATERAL (
SELECT COUNT(*) AS headcount,
AVG( emp.salary ) AS avg_salary
FROM zbtp_employee AS emp
WHERE emp.department_id = dept.department_id
AND emp.active = 'X'
) AS stats
INTO TABLE @DATA(lt_dept_stats).
GROUP BY 없이 각 부서에 대한 집계를 한 쿼리로 얻습니다.
CDS View에서 LATERAL JOIN 활용
define view ZI_CustomerLastOrder
as select from zbtp_customer as Cust
cross join lateral (
select top 1
order_date,
order_amount,
customer_id as cid
from zbtp_sales_order
where customer_id = Cust.customer_id
order by order_date descending
) as LastOrd
{
key Cust.customer_id,
Cust.customer_name,
LastOrd.order_date as last_order_date,
LastOrd.order_amount as last_order_amount
}
CDS View에서도 LATERAL JOIN 문법을 그대로 사용할 수 있습니다.
LATERAL JOIN 사용 전 확인사항
- SAP HANA 2.0 SPS 04 이상 또는 HANA Cloud 필요
- BTP ABAP Environment에서는 기본 지원
- On-Premise S/4HANA 2022 이상에서 사용 가능
- CROSS JOIN LATERAL은 매칭되는 행이 반드시 있어야 함 (없으면 해당 외부 행 제외)
- LEFT OUTER JOIN LATERAL ON 1=1은 매칭 없어도 외부 행 유지
공식 문서
ABAP Open SQL의 LATERAL JOIN 문법은 SAP ABAP CDS 공식 문서와 ABAP Keyword Documentation의 SELECT 문법 섹션에서 확인할 수 있습니다.
댓글 0
아직 댓글이 없습니다.