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

원재료 20종의 입출고 집계가 입출고상품 테이블을 스무 번 읽는다

중급SELECT유통166 / 700

상황 ​

구매팀의 「원재료 입출고 집계」는 원재료 20종마다 입출고 줄 수와 수량 합계를 낸다. 하루 수십 번 돌린다. SQL은 「상품 하나의 입출고 이력」 화면의 SQL을 복사해 조건만 바꾼 것이라 힌트도 그대로 붙어 있다. 조민우는 실행계획을 보고 "CF15에 ITM_NO 인덱스를 만들면 해결된다"라며 인덱스 생성 요청서를 올렸다. 오과장은 요청서를 받아들일지 숫자로 판단해 달라고 했다.

테이블과 인덱스 ​

  • CF01 상품: 109행 · 5블록 · CF01_PK (ITM_NO) · 원재료(ITM_CL_CD = '102') 20개
  • CF15 입출고상품: 51,497행 · 349블록 · PK (INOUT_NO, ITM_NO) · 보조 인덱스 없음
  • 원재료 줄은 6,201줄(전체의 12%, 상품마다 211 ~ 1,249줄)이다. 입출고 번호 순으로 쌓여서 한 원재료의 줄은 테이블 전체에 흩어져 있다 · 통계 최신

원본 SQL ​

sql
SELECT /*+ LEADING(p) USE_NL(i) */
       p.ITM_NO, p.ITM_NM, COUNT(*) AS io_lines, SUM(i.INOUT_QTY) AS io_qty
  FROM CF01 p, CF15 i
 WHERE p.ITM_CL_CD = '102'
   AND i.ITM_NO = p.ITM_NO
 GROUP BY p.ITM_NO, p.ITM_NM

실행계획 학습용 예시 · 행 수는 실데이터 ​

xplan
---------------------------------------------------------------------------------------
| Id  | Operation            | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
---------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |      |      1 |        |     20 |00:00:00.21 |    6985 |
|   1 |  HASH GROUP BY       |      |      1 |     36 |     20 |00:00:00.21 |    6985 |
|   2 |   NESTED LOOPS       |      |      1 |  27252 |   6201 |00:00:00.20 |    6985 |
|*  3 |    TABLE ACCESS FULL | CF01 |      1 |     36 |     20 |00:00:00.01 |       5 |
|*  4 |    TABLE ACCESS FULL | CF15 |     20 |    757 |   6201 |00:00:00.20 |    6980 |
---------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   3 - filter("P"."ITM_CL_CD"='102')
   4 - filter("I"."ITM_NO"="P"."ITM_NO")

문제 ​

  1. 6,985블록이 어디서 나오는지 Starts로 설명하시오.
  2. CF15 (ITM_NO) 인덱스를 만들어 NL로 처리할 때와 해시 조인으로 처리할 때의 일량을 비교해, 인덱스 생성 요청을 받아들일지 정하고 개선 SQL을 작성하시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자