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

평가 수와 평점은 맞는데 매출만 원장의 정확히 50배다

중급SELECT한빛유통239 / 700

상황 ​

분기 자료의 「상품별 매출 · 평점」 표를 두고 정산팀 조민우 씨가 말한다. "평가 수 50건과 평균 평점은 리뷰 화면과 똑같은데, 재무팀이 매출이 원장과 안 맞는다고 반려했습니다. 1위 ITM00071이 화면에서는 22,216,620,000, 원장에서는 444,332,400이에요." 소스 이력에는 2020-03 평가 수가 100,000 으로 나와서 COUNT(DISTINCT) 로 수정이라는 한 줄이 있다. 그 커밋을 할 때 금액 칸은 확인하지 않았다.

테이블과 인덱스 ​

  • M_ITM 상품: 100행 · 5블록 · PK_M_ITM (ITM_ID)
  • T_ORD_DET 주문상세: 200,000행 · 전체 스캔 807블록 (교재 08화 실측) · 상품당 2,000줄 · PK_T_ORD_DET (ORD_SEQ, ORD_DET_NO)
  • T_ITM_EVL 상품평가: 5,000행 · 48블록 · 상품당 50건 · PK_T_ITM_EVL (ITM_ID, EVL_LST_NO) (2020-02에 앱 리뷰를 연 뒤부터 다건이고, 그 전에는 상품당 1건이었다)
  • 원장(재무팀) = 주문상세만 상품별로 더한 것 · 회사 전체 매출 30,272,557,700
  • 100개 상품 전부에 판매와 평가가 있다 · 통계 최신

원본 SQL ​

sql
SELECT i.ITM_ID, i.ITM_NM,
       SUM(d.ORD_QTY * d.UNT_PRC)   AS sale_amt,
       COUNT(DISTINCT e.EVL_LST_NO) AS evl_cnt,
       ROUND(AVG(e.EVL_PT), 2)      AS avg_pt
  FROM M_ITM i, T_ORD_DET d, T_ITM_EVL e
 WHERE d.ITM_ID = i.ITM_ID
   AND e.ITM_ID = i.ITM_ID
 GROUP BY i.ITM_ID, i.ITM_NM
 ORDER BY sale_amt DESC

실행계획 학습용 예시 · 교재 08화 규모 ​

xplan
-----------------------------------------------------------------------------------------------
| Id  | Operation              | Name      | Starts | E-Rows | A-Rows |    A-Time   | Buffers |
-----------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT       |           |      1 |        |    100 | 00:00:01.08 |     860 |
|   1 |  SORT ORDER BY         |           |      1 |    100 |    100 | 00:00:01.08 |     860 |
|   2 |   SORT GROUP BY        |           |      1 |    100 |    100 | 00:00:01.08 |     860 |
|*  3 |    HASH JOIN           |           |      1 |    10M |    10M | 00:00:00.39 |     860 |
|*  4 |     HASH JOIN          |           |      1 |   5000 |   5000 | 00:00:00.01 |      53 |
|   5 |      TABLE ACCESS FULL | M_ITM     |      1 |    100 |    100 | 00:00:00.01 |       5 |
|   6 |      TABLE ACCESS FULL | T_ITM_EVL |      1 |   5000 |   5000 | 00:00:00.01 |      48 |
|   7 |     TABLE ACCESS FULL  | T_ORD_DET |      1 |   200K |   200K | 00:00:00.01 |     807 |
-----------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   3 - access("D"."ITM_ID"="I"."ITM_ID")
   4 - access("E"."ITM_ID"="I"."ITM_ID")

문제 ​

  1. 매출이 정확히 50배가 된 까닭을 실행계획의 줄 번호와 A-Rows로 설명하시오. 평가 수와 평균 평점은 왜 맞게 나왔는지도 설명하시오.
  2. 화면 칸(상품 · 매출 · 평가 수 · 평균 평점)은 그대로 두고, 매출이 원장과 같아지도록 SQL을 고치시오.
  3. 고친 SQL이 맞다는 것을 무엇과 어떻게 대조해 보일지 쓰시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자