Skip to content
튜닝 연습PL/SQL과 사용자 정의 함수
PLSQL-011

결과 캐시를 붙인 결제 대기 배지가 시험 DB에서는 0블록이었는데 운영에서는 그대로다

중급PLSQL한빛유통661 / 700

상황 ​

주문 접수 화면과 고객센터 화면 맨 위에는 고객의 「결제 대기 n건」 배지가 뜬다. 배지는 함수 FN_PENDING_CNT가 센다. 결과 캐시 교육을 받은 오과장이 지난주 화요일에 이 함수에 RESULT_CACHE를 붙였다. 연습 DB에서 고객 2,000명을 두 번 돌려 보니 두 번째 판은 함수 본문이 한 번도 돌지 않았다. 한 주 뒤에도 운영 화면은 빨라지지 않았고, DB CPU는 조금 늘었다. DBA가 10분 동안의 결과 캐시 통계를 보내왔다.

테이블과 인덱스 ​

  • T_ORD 주문: 100,000행 · 896블록 · ORD_ST (COMPLETE 90% · PENDING 8% · CANCEL 2%) · 운영에서는 주문 등록, 결제, 취소가 초당 약 2.5번 커밋된다
  • 인덱스 IX_T_ORD_CUS_ST (CUS_ID, ORD_ST): 이 문제에서는 있다 · 함수 안 SQL은 호출당 2블록
  • 배지는 화면을 열 때 한 번 호출되고, 운영에서는 초당 약 30번 호출된다(고객 2,000명 중 아무나)
  • 결과 캐시: 1,984칸 · result_cache_mode = MANUAL · 함수 안 SQL이 읽은 T_ORD가 의존 객체로 자동 등록된다

원본 SQL ​

sql
CREATE OR REPLACE FUNCTION FN_PENDING_CNT(p_cus_id VARCHAR2) RETURN NUMBER RESULT_CACHE IS
  v_cnt NUMBER;
BEGIN
  SELECT COUNT(*) INTO v_cnt
    FROM T_ORD
   WHERE CUS_ID = p_cus_id
     AND ORD_ST = 'PENDING';
  RETURN v_cnt;
END;
/

-- 배지 (화면을 열 때 한 번)
SELECT FN_PENDING_CNT(:cus_id) AS pending_cnt FROM dual;

실행계획 학습용 예시 ​

xplan
[연습 DB: 고객 2,000명을 두 판 (그동안 T_ORD를 고친 사람 없음)]
 판           함수 본문   찾기 (Find)   만들기 (Create)   논리 읽기
 첫 판           2,000            0             2,000        4,013
 두 번째 판          0        2,000                 0            0

[운영: 10분 동안 V$RESULT_CACHE_STATISTICS 증가분]
 Find Count                        412
 Create Count Success           17,588
 Invalidation Count             17,431
 Delete Count Valid                  0
 (그동안 배지 호출 18,000번 · T_ORD를 고친 커밋 1,503번)

[V$RESULT_CACHE_OBJECTS: 의존 객체 줄 · 10분 증가분]
 TYPE         NAME                    INVALIDATIONS
 Dependency   SQLP.T_ORD                      1,503
 Dependency   SQLP.FN_PENDING_CNT                 0

[배지 한 번 (운영 평균)]
 판                   응답 시간   논리 읽기   결과 캐시 래치 gets
 RESULT_CACHE 전       0.11 ms          2                    0
 RESULT_CACHE 후       0.13 ms          2                    4

문제 ​

  1. 연습 DB에서는 두 번째 판이 0블록이었는데 운영에서는 효과가 없는 이유를 위 통계로 설명하시오.
  2. 이 함수를 어떻게 할지 SQL로 쓰고, 결과 캐시를 붙이기 전에 무엇을 확인했어야 하는지 쓰시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자