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

영수증 번호 순 연간 판매 상세 파일이 해시 조인 뒤에 55만 줄을 다시 정렬하다가 TEMP를 쓴다

중급SELECT유통192 / 700

상황 ​

본사 회계팀은 분기 마감마다 「연간 판매 상세 파일」을 받는다. 2023년 판매상품 줄마다 판매 금액과 판매 헤더의 판매일, 요일, 매장을 붙여 영수증 번호 순으로 내려보내야 회계 시스템이 영수증 단위로 읽어 들인다(같은 영수증의 줄은 붙어 있기만 하면 된다). 파일 생성에 4초가 걸리고 돌릴 때마다 TEMP 경보가 울린다. DBA는 "조인 다음의 정렬이 TEMP를 쓴다"라고 했다. 아래는 2023년 한 해의 실행계획이다.

테이블과 인덱스 ​

  • CF10 판매: 500,000행 · 4,583블록 · CF10_PK (SLE_NO) · SLE_DT VARCHAR2(8) · 2023년 250,128건
  • CF11 판매상품: 1,096,708행 · 8,204블록 · CF11_PK (SLE_NO, ITM_NO) · SLE_NO의 앞 8자리가 판매일자 · SLE_NO 순으로 적재되어 있다
  • 2023년 판매상품 548,397줄(CF11_PK 리프 약 2,140블록, 테이블 약 4,100블록)
  • 정렬 하나가 쓸 수 있는 work area는 약 25M다 · 통계 최신

원본 SQL ​

sql
SELECT b.SLE_NO, b.ITM_NO, b.SLE_QTY, b.SLE_QTY * b.SLE_UPRC AS SLE_AMT,
       a.SLE_DT, a.SLE_DOW, a.SHP_NO
  FROM CF10 a, CF11 b
 WHERE a.SLE_DT BETWEEN '20230101' AND '20231231'
   AND b.SLE_NO = a.SLE_NO
   AND b.SLE_NO >= '20230101'
   AND b.SLE_NO <  '20240101'
 ORDER BY b.SLE_NO

실행계획 학습용 예시 ​

xplan
------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation           | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads | Writes |  OMem |  1Mem | Used-Mem | Used-Tmp|
------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |      |      1 |        |    548K|00:00:04.12 |   12787 |  5248 |   5248 |       |       |          |         |
|   1 |  SORT ORDER BY      |      |      1 |    548K|    548K|00:00:04.12 |   12787 |  5248 |   5248 |    44M|  2365K|   24M (1)|     41M |
|*  2 |   HASH JOIN         |      |      1 |    548K|    548K|00:00:01.31 |   12787 |     0 |      0 |    18M|  3245K|   21M (0)|         |
|*  3 |    TABLE ACCESS FULL| CF10 |      1 |    250K|    250K|00:00:00.07 |    4583 |     0 |      0 |       |       |          |         |
|*  4 |    TABLE ACCESS FULL| CF11 |      1 |    548K|    548K|00:00:00.19 |    8204 |     0 |      0 |       |       |          |         |
------------------------------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("B"."SLE_NO"="A"."SLE_NO")
   3 - filter(("A"."SLE_DT">='20230101' AND "A"."SLE_DT"<='20231231'))
   4 - filter(("B"."SLE_NO">='20230101' AND "B"."SLE_NO"<'20240101'))

문제 ​

  1. 4.12초와 TEMP가 계획의 어느 줄, 어느 열에서 나오는지 설명하고, 해시 조인 뒤에 정렬이 따로 필요한 이유를 쓰시오.
  2. 정렬을 줄이는 조인 방식으로 SQL을 고치시오. 두 테이블 중 어느 쪽을 먼저 두어야 하는지와 그 이유도 쓰시오.
  3. NL 조인으로 바꾸는 안과 비교하시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자