Skip to content
튜닝 연습인덱스 사용 조건
IDX-030

공휴일 열여섯 날의 주문 수를 세는데 주문 100만 건을 다 읽고 해시 조인한다

중급SELECT버거30 / 700

상황 ​

버거원 마케팅팀의 「공휴일 매출」 화면은 연도를 고르면 그해 공휴일마다 주문 수를 보여 준다. 공휴일은 본사 영업 달력 테이블에 DATE로 들어 있고, 주문 일자는 문자다. 조회가 끝나기까지 0.5초쯤 걸린다. POS DB의 접속 풀은 접속할 때마다 ALTER SESSION SET NLS_DATE_FORMAT = 'YYYYMMDD'를 실행해서 이 SQL은 에러 없이 돈다. 같은 SQL을 SQL Developer에서 돌리면 날짜 형식 에러가 난다.

테이블과 인덱스 ​

  • ORD 주문: 1,000,000행 · 22,422블록 · ORD_DT VARCHAR2(8) · 하루 약 1,368건
  • 인덱스 ORD_X01 (ORD_DT, ORD_HMS): BLEVEL 2 · 리프 약 3,570블록 · 날짜순 적재 · 통계 최신
  • BIZ_CAL 영업 달력(이 문제에서 쓰는 파생 테이블): 731행(2012-01-01 ~ 2013-12-31) · 5블록 · CAL_DT DATE(PK) · CAL_YY VARCHAR2(4) · HOLI_YN · HOLI_NM · 2013년 공휴일 16일

원본 SQL ​

sql
SELECT c.CAL_DT, c.HOLI_NM, COUNT(*) AS ord_cnt
  FROM BIZ_CAL c, ORD o
 WHERE c.CAL_YY  = :v_yy
   AND c.HOLI_YN = 'Y'
   AND o.ORD_DT  = c.CAL_DT
 GROUP BY c.CAL_DT, c.HOLI_NM
 ORDER BY c.CAL_DT

실행계획 학습용 예시 ​

xplan
[2013년]
----------------------------------------------------------------------------------------
| Id  | Operation           | Name    | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |         |      1 |        |     16 |00:00:00.52 |   22431 |
|   1 |  SORT GROUP BY      |         |      1 |     16 |     16 |00:00:00.52 |   22431 |
|*  2 |   HASH JOIN         |         |      1 |    160K|  21888 |00:00:00.51 |   22431 |
|*  3 |    TABLE ACCESS FULL| BIZ_CAL |      1 |     16 |     16 |00:00:00.01 |       5 |
|   4 |    TABLE ACCESS FULL| ORD     |      1 |   1000K|   1000K|00:00:00.18 |   22426 |
----------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("C"."CAL_DT"=TO_DATE("O"."ORD_DT"))
   3 - filter(("C"."CAL_YY"=:V_YY AND "C"."HOLI_YN"='Y'))

문제 ​

  1. 2번 줄의 TO_DATE("O"."ORD_DT")가 어디서 왔는지, 그 때문에 공휴일마다 ORD_X01로 찾아가는 NL 조인을 쓸 수 없는 이유를 설명하시오.
  2. 조인 조건을 고쳐 공휴일 16일의 주문만 읽도록 하시오. 이 SQL이 접속 풀의 NLS 설정에 기대고 있다는 점도 함께 설명하시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자