Skip to content
튜닝 연습서브쿼리와 쿼리 변환
SUBQ-013

상품은 100개뿐인데 누적 판매 순위를 내는 데 상품 마스터를 5천 번 찾는다

기초SELECT한빛유통248 / 700

상황 ​

MD팀의 「상품별 누적 판매 순위」는 신 시스템이 문을 연 뒤의 주문상세 전체를 상품명별로 묶어 판매 금액과 판매 줄 수를 보여 준다. 다음 달 상품 개편 회의를 앞두고 MD 열 명이 하루 몇 번씩 돌린다. 개발자는 상품명으로 묶어 보여 주려고 주문상세 줄마다 스칼라 서브쿼리로 상품명을 붙인 뒤 그 상품명으로 묶었다. MD팀은 "개편 때 단종 상품의 이름을 새 상품에 다시 쓸 생각"이라고 했다.

테이블과 인덱스 ​

  • T_ORD_DET 주문상세: 200,000행 · 896블록 · PK_T_ORD_DET (ORD_SEQ, ORD_DET_NO) · 주문번호 순서로 쌓여 있다 · 상품 100종류가 2,000줄씩 · 한 주문의 줄은 서로 다른 상품이고, 바로 앞 줄과 같은 상품이 이어지는 일이 상품마다 333 ~ 334번 있다
  • M_ITM 상품: 100행 · 5블록 · PK_M_ITM (ITM_ID)(블록 하나짜리 인덱스) · 지금은 상품명이 겹치지 않는다
  • 통계 최신

원본 SQL ​

sql
SELECT v.itm_nm, SUM(v.amt) AS sle_amt, COUNT(*) AS line_cnt
  FROM (SELECT (SELECT i.ITM_NM FROM M_ITM i WHERE i.ITM_ID = d.ITM_ID) AS itm_nm,
               d.ORD_QTY * d.UNT_PRC AS amt
          FROM T_ORD_DET d) v
 GROUP BY v.itm_nm
 ORDER BY sle_amt DESC

실행계획 학습용 예시 · 캐시에 자리를 얻은 상품 수는 교재 08화의 같은 데이터 실측(FILTER의 메모판)에 맞췄다 ​

xplan
----------------------------------------------------------------------------------------------------
| Id  | Operation                      | Name      | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
----------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |           |      1 |        |    100 |00:00:00.14 |   11090 |
|   1 |  SORT ORDER BY                 |           |      1 |    100 |    100 |00:00:00.14 |   11090 |
|   2 |   HASH GROUP BY                |           |      1 |    100 |    100 |00:00:00.14 |   11090 |
|   3 |    VIEW                        |           |      1 |    200K|    200K|00:00:00.12 |   11090 |
|   4 |     TABLE ACCESS BY INDEX ROWID| M_ITM     |   5097 |      1 |   5097 |00:00:00.02 |   10194 |
|*  5 |      INDEX UNIQUE SCAN         | PK_M_ITM  |   5097 |      1 |   5097 |00:00:00.01 |    5097 |
|   6 |     TABLE ACCESS FULL          | T_ORD_DET |      1 |    200K|    200K|00:00:00.03 |     896 |
----------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   5 - access("I"."ITM_ID"=:B1)

문제 ​

  1. 4번 줄의 Starts가 100이 아니라 5,097인 이유를 설명하시오.
  2. 결과가 바뀌지 않게 SQL을 고쳐 상품명을 찾는 횟수를 줄이시오. 지금처럼 상품명으로 묶으면 개편 뒤에 어떤 문제가 생기는지도 쓰시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자