Skip to content
튜닝 연습파싱과 바인드 변수
PARSE-043

협력사 납품 확인 7,102줄 반영을 addBatch로 묶었는데 13초가 그대로다

중급PLSQL유통588 / 700

상황 ​

유통 본사 협력사 연동 서버(Java)는 협력사가 보낸 납품 확인 파일(발주번호, 상품번호, 납품 수량)을 받아 줄마다 구매팀 패키지의 프로시저 PKG_PO.CONFIRM_LINE을 부른다. 프로시저는 발주 상태를 확인하고, 초과 납품이나 마감된 발주는 반송함에 적고, 나머지는 발주상품의 입고 수량을 고친다. 구매팀은 "같은 규칙을 우리 화면도 쓰니 프로시저는 그대로 써야 한다"라고 한다. 이번 달 7,102줄에 13.1초가 걸렸다. 개발자가 지난주 addBatch로 500줄씩 묶었는데 12.8초다.

테이블과 인덱스 ​

  • CF13 발주상품: 7,102행 · 57블록 · PK (ORD_NO, ITM_NO) · ORD_QTY · RCV_QTY(입고 수량) · ORD_NO는 VARCHAR2(12)
  • CF12 발주: 734행 · 10블록 · PK (ORD_NO) · ORD_PRGS_CD(진행 상태)
  • CONFIRM_LINE 한 번은 SQL을 두 번(발주 상태 SELECT, 발주상품 UPDATE 또는 반송함 INSERT) 실행하고 DB 안에서 약 0.15ms가 걸린다. 규칙 위반은 예외 없이 반송함에 적고 돌아온다.
  • 연동 서버는 DMZ에 있고 DB 서버와의 왕복은 1.6ms다. 반영은 한 트랜잭션이고 끝에 한 번 커밋한다.

원본 SQL ​

sql
// PoConfirmJob.java : 줄마다 프로시저를 부른다 (지난주 addBatch로 500줄씩 묶었다)
CallableStatement cs = conn.prepareCall("{call PKG_PO.CONFIRM_LINE(?, ?, ?)}");
int n = 0;
for (PoLine l : lines) {                       // 7,102줄
    cs.setString(1, l.ordNo);
    cs.setInt(2, l.itmNo);
    cs.setInt(3, l.qty);
    cs.addBatch();
    if (++n % 500 == 0) cs.executeBatch();
}
cs.executeBatch();
conn.commit();

-- PKG_PO.CONFIRM_LINE (구매팀 · 규칙은 고치지 않는다)
PROCEDURE CONFIRM_LINE(p_ord_no IN VARCHAR2, p_itm_no IN NUMBER, p_qty IN NUMBER);

실행계획 학습용 예시 ​

xplan
[반영 한 번 (7,102줄) · 연동 서버 세션 통계 증가분 · addBatch 판]
  경과 시간                               12.8 초
  user calls                               7,121
  SQL*Net roundtrips to/from client        7,116
  execute count                           21,330   (호출 블록 7,102 + 블록 안 SQL 14,204 + 그 밖)
  recursive calls                         14,268
  session logical reads                   29,640
  DB time                                   1.2 초
  SQL*Net message from client             7,115번 · 11.4 초 (평균 1.6 ms)

[V$SQL]
  BEGIN PKG_PO.CONFIRM_LINE(:1 , :2 , :3 ); END;                    EXECUTIONS 7,102
  SELECT ORD_PRGS_CD FROM CF12 WHERE ORD_NO = :B1                   EXECUTIONS 7,102
  UPDATE CF13 SET RCV_QTY = NVL(RCV_QTY, 0) + :B1 WHERE ...         EXECUTIONS 7,044
  INSERT INTO T_PO_REJECT ...                                       EXECUTIONS    58

[addBatch 전 · 같은 7,102줄]  13.1 초 · roundtrips 7,118 · user calls 7,124

문제 ​

  1. addBatch로 묶었는데 왕복이 거의 그대로인 이유를 위 통계로 설명하시오. 12.8초가 어디에 쓰였는지도 쓰시오.
  2. 프로시저의 규칙은 그대로 쓰면서 연동 서버와 DB 사이의 호출 수를 줄이도록 고치시오. 고친 뒤 줄지 않는 숫자는 무엇이고 왜 그런지 쓰시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자