Skip to content
튜닝 연습소트 튜닝과 페이징
SORT-024

판매 목록 첫 쪽 20줄을 여는 데 2.4초가 걸린다

중급SELECT유통329 / 700

상황 ​

본사 영업관리팀의 「판매 목록」은 최근 판매부터 한 쪽에 20건을 보여 주고, 판매마다 품목 수와 판매 금액(수량 × 단가의 합)을 붙인다. 영업관리팀 30명이 하루 약 4,000번 여는데 첫 쪽부터 2.4초가 걸린다. 판매번호는 판매일자와 그날의 순번으로 매겨서 판매번호 역순이 곧 최신순이다(교재 09화에서 재서 확인한 전제다).

테이블과 인덱스 ​

  • CF10 판매: 500,000행 · 4,583블록 · CF10_PK (SLE_NO) · 판매번호 순서와 쌓인 순서가 거의 같다.
  • CF11 판매상품: 1,096,708행 · 8,204블록 · CF11_PK (SLE_NO, ITM_NO) · 판매당 평균 2.2품목 · 한 판매의 품목 줄은 같은 블록에 모여 있다.
  • 판매상품이 하나도 없는 판매는 지금 0건이다(판매 저장 프로시저가 두 테이블을 한 트랜잭션으로 넣는다). 둘 사이에 FK는 없다.
  • 통계는 최신이다. PGA가 넉넉해 지금은 디스크 정렬이 없다.

원본 SQL ​

sql
SELECT *
  FROM (SELECT h.SLE_NO, h.SLE_DT, h.SHP_NO,
               COUNT(*)                    AS itm_cnt,
               SUM(d.SLE_QTY * d.SLE_UPRC) AS sle_amt
          FROM CF10 h, CF11 d
         WHERE d.SLE_NO = h.SLE_NO
         GROUP BY h.SLE_NO, h.SLE_DT, h.SHP_NO
         ORDER BY h.SLE_NO DESC)
 WHERE ROWNUM <= 20

실행계획 학습용 예시 ​

xplan
--------------------------------------------------------------------------------------------------------------
| Id  | Operation                | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Used-Mem |
--------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT         |      |      1 |        |     20 |00:00:02.41 |   12787 |          |
|*  1 |  COUNT STOPKEY           |      |      1 |        |     20 |00:00:02.41 |   12787 |          |
|   2 |   VIEW                   |      |      1 |    500K|     20 |00:00:02.41 |   12787 |          |
|*  3 |    SORT ORDER BY STOPKEY |      |      1 |    500K|     20 |00:00:02.41 |   12787 | 4096 (0) |
|   4 |     HASH GROUP BY        |      |      1 |    500K|    500K|00:00:02.17 |   12787 |   47M (0)|
|*  5 |      HASH JOIN           |      |      1 |   1096K|   1096K|00:00:01.18 |   12787 |   34M (0)|
|   6 |       TABLE ACCESS FULL  | CF10 |      1 |    500K|    500K|00:00:00.06 |    4583 |          |
|   7 |       TABLE ACCESS FULL  | CF11 |      1 |   1096K|   1096K|00:00:00.12 |    8204 |          |
--------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter(ROWNUM<=20)
   3 - filter(ROWNUM<=20)
   5 - access("D"."SLE_NO"="H"."SLE_NO")

문제 ​

  1. 화면은 20줄인데 실행계획의 어느 줄에서 몇 행을 조인하고 묶는지 쓰고, 첫 쪽이 2.4초 걸리는 까닭을 설명하시오.
  2. 결과가 바뀌지 않게 SQL을 고치시오. 고친 SQL이 원래 SQL과 같은 결과를 내려면 데이터가 어떤 조건을 만족해야 하는지, 그 조건이 깨지면 화면이 어떻게 달라지는지도 쓰시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자