Search

[필수:성능]목록 조회 후 N+1 API 호출

조회된 목록에 필요한 단가 정보를 기존 상품 API로 행마다 다시 요청하면, DB 조인 한 번으로 해결할 수 있는 작업이 수백~수천 번의 네트워크 호출로 확대될 수 있습니다.
예시: 주문상세 1,000건을 화면에 표시하면서 각 상품의 기준 판매단가를 함께 보여주는 경우입니다. 실제 startdbpg.tr_ord_det(주문상세)과 startdbpg.ms_item_prc_hist(상품 단가 이력)을 사용합니다. 2024-01-01에 적용되는 단가를 조회한다고 가정합니다.

BAD

목록 1회 조회 + 행마다 상품단가 API 1회 호출
-- ① 화면에 표시할 주문상세 1,000건 조회 SELECT d.ord_no ,d.ord_det_no ,d.item_id FROM startdbpg.tr_ord_det d ORDER BY d.ord_no DESC, d.ord_det_no DESC LIMIT 1000 ;
SQL
복사
-- ② 프로그램 슈도코드 LIST = 주문상세_목록_조회() -- 1회 FOR EACH ROW IN LIST LOOP PRICE = 상품단가_API_호출( ROW.item_id, 기준일 = '2024-01-01' ) -- 각 행마다 호출 ROW.기준단가 = PRICE END LOOP 화면에 LIST 출력
Plain Text
복사
총 요청: 목록 조회 1회 + 단가 API 최대 1,000회 = 1,001회(동일 상품을 재호출하고 별도 캐시가 없는 경우).

GOOD

목록 1,000건을 먼저 확정하고 단가 이력을 조인하여 한 번에 조회
SELECT d.ord_no ,d.ord_det_no ,d.item_id ,p.sale_prc AS base_sale_prc FROM ( SELECT x.ord_no ,x.ord_det_no ,x.item_id FROM startdbpg.tr_ord_det x ORDER BY x.ord_no DESC, x.ord_det_no DESC LIMIT 1000 ) d LEFT JOIN startdbpg.ms_item_prc_hist p ON p.item_id = d.item_id AND DATE '2024-01-01' >= p.prc_start_dt AND ( p.prc_end_dt IS NULL OR DATE '2024-01-01' <= p.prc_end_dt ) ORDER BY d.ord_no DESC, d.ord_det_no DESC ;
SQL
복사
총 요청: 목록과 기준단가를 가져오는 DB 조회 1회.

핵심 설명

•
BAD: 목록 1,000건을 읽은 다음 각 행의 item_id로 단가 조회 API를 반복 호출하면 N+1 API 호출이 됩니다. 각 요청마다 네트워크 왕복, 서버 처리, DB 접근 및 응답 처리 비용이 발생하여 화면 표시가 지연되고, API 서버와 DB에 불필요한 부하를 줄 수 있습니다.
•
GOOD: 필요한 정보가 같은 DB에서 조인 가능한 경우 목록 조회 SQL에서 단가 이력을 함께 조회합니다. 주문상세를 먼저 1,000건으로 제한한 뒤 상품 단가를 조인하므로, 화면에 표시하지 않을 행까지 단가를 조회할 필요가 없습니다.
•
TIP ①: 상품정보가 별도 서비스에 있어 직접 DB 조인이 허용되지 않는다면, 상품 ID 목록을 한 번에 전달하는 일괄 조회 API를 사용합니다. 상품 ID 중복 제거, 캐시 활용도 검토할 수 있습니다. 서비스 경계를 무시한 직접 DB 접근을 무조건 권장하는 것은 아닙니다.
•
TIP ②: 실제 주문상세에는 tr_ord_det.sale_prc도 존재합니다. 주문 당시 판매단가가 필요한 화면이라면 이미 저장된 값을 먼저 확인하고, 특정 기준일의 상품 기준단가가 필요한 경우에만 ms_item_prc_hist.sale_prc를 사용해야 합니다. 같은 '단가'라도 업무적 의미가 다릅니다.
•
TIP ③: 단가 이력은 같은 상품·기준일에 유효한 행이 한 건만 존재해야 목록 행이 중복되지 않습니다. 예제의 유효기간 경계는 종료일을 포함하는 데이터 모델을 전제로 합니다.

요청 횟수 비교

처리 방식
목록 조회
단가 정보 조회
합계
BAD — 행별 API 호출
1회
최대 1,000회
최대 1,001회
GOOD — 조인 조회
조인 포함 1회
별도 호출 없음
1회
대안 — 일괄 API
1회
1회(일괄 지원 시)
2회
요청 횟수는 1,000개 화면 행을 대상으로 하는 구조적 예시입니다. 실제 처리시간은 API 지연, 캐시 적중률, 동시 호출 방식, 쿼리 및 서비스 구조에 따라 달라집니다.
기존 스키마를 대상으로 읽기 전용 조회를 검증했으며, 기준일 2024-01-01에서 페이지 대상 1,000건과 조인 결과 1,000건이 일치합니다. 테이블 구조 및 데이터는 변경하지 않았습니다.