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

매시 정각이 되면 1~2분 동안 매장 POS 결제가 멈칫한다

중급SELECT버거557 / 700

상황 ​

버거 본사 DB에는 2014년 겨울 ORA-04031이 난 뒤 DBA가 걸어 둔 스케줄러 잡이 있다. 매시 정각에 공유 풀을 비우는 잡이다. 그 뒤로 04031은 다시 나지 않았다. 요즘 매장들에서 정각마다 1~2분씩 결제가 멈칫한다는 연락이 온다. 점심 12시 정각이 가장 심하다. 오과장이 물었다. "공유 풀을 비우고 나면 오히려 깨끗해야 하는 거 아닌가요?"

테이블과 인덱스 ​

  • ORD 주문: 1,000,000행 · 22,422블록 · ORD_X01 (ORD_DT, ORD_HMS) · SHOP_NO는 'SH0001' 모양(매장 200곳)
  • 매장마다 POS 2대(DB 세션 400개)와 주방 모니터 1대가 붙어 있다. POS 문장은 바인드 변수로 쓰여 있다.
  • 주방 모니터는 3초마다 "마지막으로 본 시각 이후의 주문"을 읽는다.
  • CURSOR_SHARING = EXACT · 공유 풀 2GB

원본 SQL ​

sql
-- 스케줄러 잡 FLUSH_SP_HOURLY (2014년 DBA) : 매시 정각
BEGIN
  DBMS_SCHEDULER.CREATE_JOB(
    job_name        => 'FLUSH_SP_HOURLY',
    job_type        => 'PLSQL_BLOCK',
    job_action      => 'BEGIN EXECUTE IMMEDIATE ''ALTER SYSTEM FLUSH SHARED_POOL''; END;',
    repeat_interval => 'FREQ=HOURLY; BYMINUTE=0; BYSECOND=0',
    enabled         => TRUE);
END;

-- 주방 모니터 : 3초마다 · 매장, 날짜, 마지막으로 본 시각을 문자열로 이어 붙인다
SELECT ORD_NO, ORD_HMS
  FROM ORD
 WHERE SHOP_NO = 'SH0042'
   AND ORD_DT  = '20131231'
   AND ORD_HMS > '121503'
 ORDER BY ORD_HMS

실행계획 학습용 예시 ​

xplan
[V$SYSSTAT 1분 차분 · parse count (hard)]
  11:58     4,260
  11:59     4,310
  12:00     5,940    ← 공유 풀을 비운 직후
  12:01     4,480
  12:02     4,290

[ASH · 12:00:00 ~ 12:01:30 · 활성 세션 표본 (평소 같은 시간대의 평균 활성 세션은 6명 안팎)]
  이벤트                         표본 비율   평균 활성 세션
  cursor: pin S wait on X            34%           41
  library cache: mutex X             17%           20
  latch: shared pool                 12%           14
  row cache mutex                     8%           10
  CPU                                22%           26

[POS 결제 INSERT 응답 시간]  평소 p99 0.02초 · 12:00 ~ 12:01 p99 3.8초

[V$SQLAREA · 11:59 (비우기 직전) · FORCE_MATCHING_SIGNATURE로 묶은 상위 무리]
  PARENTS   EXECS     MB   SAMPLE
    3,940   3,960   57.8   SELECT ORD_NO, ORD_HMS FROM ORD WHERE SHOP_NO = 'SH0042' AND ORD_DT = '20131231' AND ORD_HMS > '115904' ORDER BY ORD_HMS
       11     240    0.2   SELECT ITEM_NM, SALE_YN FROM ITEM WHERE ITEM_TYPE_CD = '10' …

[주방 모니터 한 번 실행의 계획]
----------------------------------------------------------------------------------------------
| Id  | Operation                   | Name    | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
----------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |         |      1 |        |      1 |00:00:00.01 |       3 |
|*  1 |  TABLE ACCESS BY INDEX ROWID| ORD     |      1 |      1 |      1 |00:00:00.01 |       3 |
|*  2 |   INDEX RANGE SCAN          | ORD_X01 |      1 |      7 |      2 |00:00:00.01 |       2 |
----------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter("SHOP_NO"='SH0042')
   2 - access("ORD_DT"='20131231' AND "ORD_HMS">'121503')

문제 ​

  1. 정각마다 결제가 멈칫하는 이유를 ASH와 분별 하드 파싱 수로 설명하시오. 하드 파싱 수는 크게 늘지 않았는데 세션이 몰린 까닭도 쓰시오.
  2. 2014년의 ORA-04031을 부른 원인을 위 자료에서 찾아 고치고, 스케줄러 잡을 어떻게 할지 쓰시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자