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

03화에서 판매 헤더를 고쳤는데 월 매출 집계는 아직 8,552블록을 읽는다

실전SELECT유통170 / 700

상황 ​

03화에서 「월 매출 집계」의 TO_DATE 가공을 걷어 내고 SLE_DT 인덱스를 만들었다. CF10 쪽은 4,510 → 478블록으로 줄었지만 전체는 아직 8,552블록이다. 그날 리포트의 '남긴 빚' 칸에는 "조인 쪽 CF11 FULL 8,075는 06화로"라고 적혀 있다. 선배는 "NL로 바꿀지, 해시를 그대로 둘지, 다른 길이 있는지 숫자로 비교해서 가져와"라고 했다.

테이블과 인덱스 ​

  • CF10 판매: 500,000행 · 4,583블록 · CF10_PK (SLE_NO) · IX_CF10_SLE_DT (SLE_DT) (03화) · 2023년 6월 20,953행
  • CF11 판매상품: 1,096,708행 · 8,204블록 · CF11_PK (SLE_NO, ITM_NO) 리프 약 4,300블록 · 2023년 6월 45,935줄, 377,266,500원 · 판매 번호 순으로 쌓여 한 달치 줄이 약 710블록에 모여 있다
  • SLE_NO는 SLE_DT에 일련번호를 붙인 모양이다('20230601-0308'). 지금 데이터에서 앞 8자리와 SLE_DT가 다른 행은 0건이고, 판매 헤더가 없는 판매상품도 0건이다. 그러나 이를 지키는 제약(CHECK, FK)은 없다
  • 통계 최신

원본 SQL ​

sql
SELECT COUNT(*), SUM(b.SLE_QTY * b.SLE_UPRC)
  FROM CF10 a, CF11 b
 WHERE a.SLE_NO = b.SLE_NO
   AND a.SLE_DT BETWEEN '20230601' AND '20230630'

실행계획 실측 · 교재 03화 (개선안은 학습용 예시) ​

xplan
-------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                              | Name           | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  Used-Mem |
-------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                       |                |      1 |        |      1 |00:00:00.21 |    8552 |           |
|   1 |  SORT AGGREGATE                        |                |      1 |      1 |      1 |00:00:00.21 |    8552 |           |
|*  2 |   HASH JOIN                            |                |      1 |   5865 |  45935 |00:00:00.20 |    8552 | 2061K (0) |
|   3 |    TABLE ACCESS BY INDEX ROWID BATCHED | CF10           |      1 |   2673 |  20953 |00:00:00.01 |     478 |           |
|*  4 |     INDEX RANGE SCAN                   | IX_CF10_SLE_DT |      1 |   2673 |  20953 |00:00:00.01 |      62 |           |
|   5 |    TABLE ACCESS FULL                   | CF11           |      1 |  1096K |  1096K |00:00:00.06 |    8074 |           |
-------------------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("A"."SLE_NO"="B"."SLE_NO")
   4 - access("A"."SLE_DT">='20230601' AND "A"."SLE_DT"<='20230630')

문제 ​

  1. 이 SQL을 NL 조인(CF10 → CF11_PK)으로 바꾸면 Buffers가 어떻게 될지 Starts로 어림하고, 해시 조인을 유지할 때와 비교하시오.
  2. CF11 쪽 일량을 줄이는 개선안을 작성하시오. 그 안이 결과를 바꾸지 않는다는 근거와, 그 근거가 깨질 때 생기는 일을 서술하시오.
  3. CF10 조인을 아예 없애는 안과 CF11에 커버링 인덱스를 만드는 안까지 포함해 비교하고, 어떤 안을 권할지 서술하시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자