Skip to content
튜닝 연습조인 튜닝
JOIN-032

혼자 돌리면 2초인 연간 상품 · 요일 리포트가 월초 아침에는 10초 가까이 걸린다

실전SELECT유통182 / 700

상황 ​

매월 1일 07시에 본사 리포트 다섯 개가 한꺼번에 돌고, 같은 시각에 BI팀의 대량 추출도 시작된다. 그중 「연간 상품 · 요일 판매」 리포트는 낮에 혼자 돌리면 2초인데 월초 아침에는 10초 가까이 걸린다. 다섯 리포트는 모두 2023년 CF10 × CF11 조인을 묶는 기준만 달리한 SQL이다. 인프라팀은 pga_aggregate_target을 512M에서 1G로 올리자고 하고, 개발팀은 리포트 세션만 MANUAL로 크게 잡자고 한다. 오과장이 두 안을 포함해 비교 의견서를 내라고 했다.

테이블과 인덱스 ​

  • CF10 판매: 500,000행 · 4,583블록 · CF10_PK (SLE_NO) · IX_CF10_SLE_DT (SLE_DT) · 2023년 250,000건 (SLE_DT가 문자라 옵티마이저는 50,763건으로 본다, 03화)
  • CF11 판매상품: 1,096,708행 · 8,204블록 · CF11_PK (SLE_NO, ITM_NO) · 2023년 판매상품 548,213줄
  • 다섯 리포트: ① 상품 × 요일 (아래 SQL) ② 매장 × 월 ③ 상품 × 월 ④ 매장 × 요일 ⑤ 매장 × 상품. 조인과 기간은 모두 같다
  • V$PGASTAT: 낮 15시 global memory bound 104,857,600 · 1일 07시 02분 5,242,880 (total PGA allocated 509M, 그중 BI 추출 세션의 정렬이 약 350M)
  • 통계 최신 · workarea_size_policy AUTO

원본 SQL ​

sql
SELECT b.ITM_NO, a.SLE_DOW, COUNT(*) AS sle_lines, SUM(b.SLE_QTY) AS sle_qty
  FROM CF10 a, CF11 b
 WHERE a.SLE_DT BETWEEN '20230101' AND '20231231'
   AND b.SLE_NO = a.SLE_NO
 GROUP BY b.ITM_NO, a.SLE_DOW

실행계획 학습용 예시 ​

xplan
[낮 15시 · 혼자]
---------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation           | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads | Writes |  OMem |  1Mem | Used-Mem | Used-Tmp|
---------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |      |      1 |        |    616 |00:00:01.92 |   12787 |     0 |      0 |       |       |          |         |
|   1 |  HASH GROUP BY      |      |      1 |    616 |    616 |00:00:01.92 |   12787 |     0 |      0 |  1321K|  1321K| 1255K (0)|         |
|*  2 |   HASH JOIN         |      |      1 |    111K|    548K|00:00:01.71 |   12787 |     0 |      0 |    15M|  2420K|   16M (0)|         |
|*  3 |    TABLE ACCESS FULL| CF10 |      1 |  50763 |    250K|00:00:00.21 |    4583 |     0 |      0 |       |       |          |         |
|   4 |    TABLE ACCESS FULL| CF11 |      1 |   1096K|   1096K|00:00:00.63 |    8204 |     0 |      0 |       |       |          |         |
---------------------------------------------------------------------------------------------------------------------------------------------

[1일 07시 02분 · 리포트 다섯 개와 BI 추출이 함께]
---------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation           | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads | Writes |  OMem |  1Mem | Used-Mem | Used-Tmp|
---------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |      |      1 |        |    616 |00:00:09.64 |   12787 |  1871 |   1871 |       |       |          |         |
|   1 |  HASH GROUP BY      |      |      1 |    616 |    616 |00:00:09.64 |   12787 |  1871 |   1871 |  1321K|  1321K| 1255K (0)|         |
|*  2 |   HASH JOIN         |      |      1 |    111K|    548K|00:00:09.42 |   12787 |  1871 |   1871 |    15M|  2420K| 5120K (1)|      15M|
|*  3 |    TABLE ACCESS FULL| CF10 |      1 |  50763 |    250K|00:00:00.24 |    4583 |     0 |      0 |       |       |          |         |
|   4 |    TABLE ACCESS FULL| CF11 |      1 |   1096K|   1096K|00:00:00.66 |    8204 |     0 |      0 |       |       |          |         |
---------------------------------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("B"."SLE_NO"="A"."SLE_NO")
   3 - filter(("A"."SLE_DT">='20230101' AND "A"."SLE_DT"<='20231231'))

문제 ​

  1. 같은 계획, 같은 Buffers인데 07시에만 다섯 배 느린 이유를 두 실행계획의 메모리 열과 V$PGASTAT으로 설명하시오.
  2. ① pga_aggregate_target 증설 ② 리포트 세션만 MANUAL로 크게 ③ 리포트 실행 시각 나누기 ④ 다섯 리포트가 함께 쓰는 일 요약 테이블, 네 안을 효과와 대가로 비교하시오.
  3. 권하는 안을 SQL(DDL 포함)로 작성하고, 다섯 리포트 전체의 일량이 어떻게 바뀌는지 숫자로 정리하시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자