Skip to content
튜닝 연습옵티마이저와 통계
OPT-041

2012년에 넣은 옵티마이저 설정 세 줄을 기본값으로 되돌리자는데 무엇이 바뀔지 아무도 모른다

실전DDL유통631 / 700

상황 ​

본사 유통 DB의 spfile에는 2012년 이관 때 넣은 세 줄이 있다. optimizer_mode = FIRST_ROWS, optimizer_index_cost_adj = 20, optimizer_index_caching = 80. 넣은 사람도 이유도 남아 있지 않다. 박팀장은 다음 달 정기 점검 때 기본값으로 되돌리자고 했다. "단, 점장 화면이 하나라도 느려지면 안 돼요." 조민우가 복사본(같은 데이터, 같은 통계)에서 대표 SQL 셋을 지금 설정 세션과 기본값 세션으로 각각 쟀다.

테이블과 인덱스 ​

  • CF10 판매: 500,000행 · 4,583블록 · CF10_PK (SLE_NO)(SLE_NO는 날짜로 시작해 판매 순서와 같다) · IX_CF10_SLE_DT (SLE_DT) · 매장 6곳(매장당 약 83,000건) · SLE_DT VARCHAR2(8)
  • CF11 판매상품: 1,096,708행 · 8,204블록 · CF11_PK (SLE_NO, ITM_NO) 높이 3
  • CF12 발주 734행 · 10블록 / CF13 발주상품 7,102행 · 57블록 · 각각 PK(ORD_NO, ORD_NO + ITM_NO)
  • SQL Plan Management: 베이스라인 없음 · 이 DB의 반복 SQL은 대부분 하루에 한 번 이상 돈다

원본 SQL ​

sql
-- 박팀장 안 (다음 달 정기 점검 · 재기동)
ALTER SYSTEM RESET optimizer_mode           SCOPE = SPFILE;
ALTER SYSTEM RESET optimizer_index_cost_adj SCOPE = SPFILE;
ALTER SYSTEM RESET optimizer_index_caching  SCOPE = SPFILE;

-- S1 점장 화면 「최근 판매」 : 화면은 20행만 받고 커서를 닫는다 (하루 3,000번)
SELECT SLE_NO, SLE_DT, SLE_HMS
  FROM CF10
 WHERE SHP_NO = :shp
 ORDER BY SLE_NO DESC;

-- S2 본부 「월 상품 판매」 (하루 40번)
SELECT b.ITM_NO, SUM(b.SLE_QTY) AS qty
  FROM CF10 a, CF11 b
 WHERE a.SLE_DT BETWEEN :d1 AND :d2
   AND b.SLE_NO = a.SLE_NO
 GROUP BY b.ITM_NO;

-- S3 「발주 상세」 (하루 500번)
SELECT d.ITM_NO, d.ORD_QTY
  FROM CF12 h, CF13 d
 WHERE h.ORD_NO = :ord
   AND d.ORD_NO = h.ORD_NO;

실행계획 학습용 예시 · 복사본에서 두 설정으로 잰 값 ​

xplan
[복사본 측정 — 두 설정]
          지금 설정 (FIRST_ROWS · 20 · 80)                     기본값 (ALL_ROWS · 100 · 0)
 S1   INDEX FULL SCAN DESCENDING CF10_PK · 7블록 (20행에서 멈춘다)   TABLE ACCESS FULL + SORT ORDER BY · 4,583블록 · 0.19초
 S2   NESTED LOOPS (CF11_PK 20,953번) · 84,500블록 · 0.31초        HASH JOIN (CF11 FULL) · 8,457블록 · 0.12초
 S3   NESTED LOOPS (PK 두 번) · 7블록                               같은 계획 · 7블록

[S2 — 지금 설정 · 6월]
-------------------------------------------------------------------------------------------------------
| Id  | Operation                       | Name           | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
-------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                |                |      1 |        |    109 |00:00:00.31 |   84500 |
|   1 |  HASH GROUP BY                  |                |      1 |    109 |    109 |00:00:00.31 |   84500 |
|*  2 |   FILTER                        |                |      1 |        |  45960 |00:00:00.29 |   84500 |
|   3 |    NESTED LOOPS                 |                |      1 |   5858 |  45960 |00:00:00.28 |   84500 |
|   4 |     NESTED LOOPS                |                |      1 |   5858 |  45960 |00:00:00.17 |   63112 |
|   5 |      TABLE ACCESS BY INDEX ROWID| CF10           |      1 |   2673 |  20953 |00:00:00.02 |     253 |
|*  6 |       INDEX RANGE SCAN          | IX_CF10_SLE_DT |      1 |   2673 |  20953 |00:00:00.01 |      60 |
|*  7 |      INDEX RANGE SCAN           | CF11_PK        |  20953 |      2 |  45960 |00:00:00.11 |   62859 |
|   8 |     TABLE ACCESS BY INDEX ROWID | CF11           |  45960 |      2 |  45960 |00:00:00.10 |   21388 |
-------------------------------------------------------------------------------------------------------

[S1 — 기본값 · 화면이 20행을 받고 닫았을 때]
-------------------------------------------------------------------------------------------------------
| Id  | Operation                       | Name           | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
-------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                |                |      1 |        |     20 |00:00:00.19 |    4583 |
|   1 |  SORT ORDER BY                  |                |      1 |  83333 |     20 |00:00:00.19 |    4583 |
|*  2 |   TABLE ACCESS FULL             | CF10           |      1 |  83333 |  83312 |00:00:00.07 |    4583 |
-------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter(:D1<=:D2)                              (S2)
   6 - access("A"."SLE_DT">=:D1 AND "A"."SLE_DT"<=:D2)  (S2)
   7 - access("B"."SLE_NO"="A"."SLE_NO")             (S2)
   2 - filter("SHP_NO"=:SHP)                         (S1)

문제 ​

  1. 세 SQL이 설정을 되돌리면 각각 어떻게 바뀌는지 그 이유를 세 파라미터로 설명하고, 하루 실행 횟수를 곱해 득실을 쓰시오.
  2. 점장 화면이 하나도 느려지지 않게 되돌리는 절차를 되돌리기 전, 되돌린 날, 그 뒤로 나눠 SQL로 쓰시오.
  3. 설정은 그대로 두고 S2만 힌트로 고치는 안, 화면과 배치의 세션 설정을 나누는 안과 비교해 부작용을 서술하시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자