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

주문상세 조인을 걷어냈는데도 「연간 주문 목록」 내려받기는 그대로 무겁다

중급SELECT한빛유통346 / 700

상황 ​

정산팀의 「연간 주문 목록」 내려받기는 2024년 주문에 고객 이름과 등급을 붙여 엑셀로 내린다(순서는 엑셀에서 정한다). 2년 전에는 '특정 상품군이 들어간 주문만' 고르려고 주문상세(T_ORD_DET)를 함께 조인했는데, 주문 하나가 상세 줄 수만큼 여러 번 나와서 DISTINCT를 붙였다. 지난달 상품군 조건이 없어지면서 개발자가 주문상세 조인을 걷어냈다. 그런데 내려받기는 여전히 2.8초가 걸리고, 월초에 여러 명이 동시에 받으면 TEMP를 쓴다. 개발자는 "조인을 하나 뺐는데 왜 그대로인지 모르겠다"고 한다.

테이블과 인덱스 ​

  • T_ORD_BIG: 1,000,000행 · 5,826블록 · ORD_SEQ NOT NULL(시퀀스로 채운다, 유일 제약은 없다) · 2024년 주문 333,968행
  • M_CUS: 2,000행 · 30블록 · PK_M_CUS (CUS_ID) · T_ORD_BIG.CUS_ID는 NOT NULL이고 모든 값이 M_CUS에 있다
  • 내려받기 도구는 한 번에 5,000행씩 가져온다. 월초에는 동시 작업이 많아 work area 상한이 약 12MB다. 통계는 최신이다.

원본 SQL ​

sql
SELECT DISTINCT o.ORD_SEQ, o.ORD_DT, o.CUS_ID, c.CUS_NM, c.CUS_GD, o.ORD_ST, o.ORD_AMT
  FROM T_ORD_BIG o, M_CUS c
 WHERE c.CUS_ID = o.CUS_ID
   AND o.ORD_DT >= DATE '2024-01-01'
   AND o.ORD_DT <  DATE '2025-01-01'

실행계획 학습용 예시 ​

xplan
[월초 · 동시 내려받기]
-----------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation           | Name      | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem | Used-Tmp|
-----------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |           |      1 |        |    333K|00:00:02.84 |    5863 |       |       |          |         |
|   1 |  HASH UNIQUE        |           |      1 |    334K|    333K|00:00:02.84 |    5863 |    24M|  3511K|   12M (1)|      21M|
|*  2 |   HASH JOIN         |           |      1 |    334K|    333K|00:00:00.33 |    5856 |  1335K|  1335K| 1572K (0)|         |
|   3 |    TABLE ACCESS FULL | M_CUS     |      1 |   2000 |   2000 |00:00:00.01 |      30 |       |       |          |         |
|*  4 |    TABLE ACCESS FULL | T_ORD_BIG |      1 |    334K|    333K|00:00:00.12 |    5826 |       |       |          |         |
-----------------------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("C"."CUS_ID"="O"."CUS_ID")
   4 - filter(("O"."ORD_DT">=TO_DATE(' 2024-01-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND
              "O"."ORD_DT"<TO_DATE(' 2025-01-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss')))

문제 ​

  1. 주문상세 조인을 걷어낸 지금 이 SQL에서 DISTINCT가 지우는 줄이 있는지 테이블 관계로 판단하고, 1번 줄이 하는 일과 그 비용을 실행계획으로 설명하시오.
  2. 결과가 바뀌지 않게 SQL을 고치고, 고치기 전에 무엇을 확인해야 하는지 쓰시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자