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

「보류 건 제외」를 켜면 숫자가 나오고, 끄면 30일 내내 0건이 된다

기초SELECT한빛유통269 / 700

상황 ​

정산팀의 「일자별 주문 현황」은 기간을 고르면 일자별 주문 건수와 금액을 보여 준다. 취소 건은 늘 빼고, 화면 위의 「보류 건 제외」를 켜면 보류(PENDING)도 뺀다. 지난주 화면을 새 프레임워크로 옮긴 뒤 이상한 일이 생겼다. 「보류 건 제외」를 켜면 숫자가 나오는데, 끄면 30일 내내 0건이다. 새 화면은 체크 상자가 꺼져 있으면 :v_excl에 빈 문자열('')을 넘긴다. 예전 화면은 꺼져 있을 때 그 조건 줄을 SQL에서 아예 빼고 보냈다.

테이블과 인덱스 ​

  • T_ORD_BIG: 1,000,000행 · 5,826블록 · 2024년 6월 27,390행 = COMPLETE 24,651 · PENDING 2,190 · CANCEL 549
  • 인덱스 IX_ORD_BIG_DT_ST (ORD_DT, ORD_ST, ORD_AMT): 리프 약 3,850블록 · 6월 구간 약 105블록
  • 통계 최신 · 바인드 :v_from = '20240601', :v_to = '20240701'

원본 SQL ​

sql
SELECT ORD_DT, COUNT(*) AS ord_cnt, SUM(ORD_AMT) AS ord_amt
  FROM T_ORD_BIG
 WHERE ORD_DT >= TO_DATE(:v_from, 'YYYYMMDD')
   AND ORD_DT <  TO_DATE(:v_to, 'YYYYMMDD')
   AND ORD_ST NOT IN ('CANCEL', :v_excl)
 GROUP BY ORD_DT
 ORDER BY ORD_DT

실행계획 학습용 예시 · 상태별 건수는 적재 데이터 그대로 ​

xplan
-------------------------------------------------------------------------------------------------
| Id  | Operation            | Name             | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
-------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |                  |      1 |        |      0 |00:00:00.01 |     108 |
|   1 |  SORT GROUP BY NOSORT|                  |      1 |     30 |      0 |00:00:00.01 |     108 |
|*  2 |   FILTER             |                  |      1 |        |      0 |00:00:00.01 |     108 |
|*  3 |    INDEX RANGE SCAN  | IX_ORD_BIG_DT_ST |      1 |  26812 |      0 |00:00:00.01 |     108 |
-------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter(TO_DATE(:V_TO,'YYYYMMDD')>TO_DATE(:V_FROM,'YYYYMMDD'))
   3 - access("ORD_DT">=TO_DATE(:V_FROM,'YYYYMMDD') AND "ORD_DT"<TO_DATE(:V_TO,'YYYYMMDD'))
       filter(("ORD_ST"<>'CANCEL' AND "ORD_ST"<>:V_EXCL))

[바인드]  :V_FROM = '20240601' · :V_TO = '20240701' · :V_EXCL = NULL (화면이 넘긴 '')
[켰을 때]  :V_EXCL = 'PENDING' · 같은 계획 · 3번 줄 A-Rows 24,651 · 결과 30행 · Buffers 108

문제 ​

  1. 「보류 건 제외」를 끄면 0건이 되는 까닭을 NOT IN의 뜻과 오라클의 빈 문자열 처리로 설명하시오. 실행계획의 어느 줄에서 확인할 수 있는지도 쓰시오.
  2. 체크 상자를 켜든 끄든 맞는 결과가 나오도록 SQL을 고치시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자