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

「최근 결제」 목록 맨 위에 결제도 안 된 주문 20건이 뜬다

중급SELECT한빛유통42 / 700

상황 ​

결제팀 모니터의 「최근 결제」 칸은 방금 결제된 주문 20건을 보여 준다. 결제팀 여섯 명이 하루 종일 띄워 두고 30초마다 새로 고친다. 결제 연동을 개편한 뒤로 이 칸에는 결제 시각이 빈 주문만 20줄 뜬다. 조민우는 "PAY_DT 인덱스가 있으니 역순으로 읽으면 될 것 같은데, 힌트를 줘도 정렬을 한다"고 한다.

테이블과 인덱스 ​

  • T_ORD 주문: 100,000행 · 896블록 · PK_T_ORD (ORD_SEQ)
  • PAY_DT DATE: 결제 시각(시분초 있음) · 결제 전이면 NULL · NOT NULL 제약 없음 · 지금 미결제 41건 (문제 설정: IDX-004와 같다. 2024.12 결제 연동 개편 뒤의 모습이라고 본다)
  • 인덱스 IX_T_ORD_PAY (PAY_DT): BLEVEL 1 · 리프 265 · 통계 최신

원본 SQL ​

sql
SELECT *
  FROM (SELECT ORD_SEQ, CUS_ID, PAY_DT, PAY_TP, PAY_AMT
          FROM T_ORD
         ORDER BY PAY_DT 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:00.03 |     896 |          |
|*  1 |  COUNT STOPKEY           |       |      1 |        |     20 |00:00:00.03 |     896 |          |
|   2 |   VIEW                   |       |      1 |    100K|     20 |00:00:00.03 |     896 |          |
|*  3 |    SORT ORDER BY STOPKEY |       |      1 |    100K|     20 |00:00:00.03 |     896 | 4096  (0)|
|   4 |     TABLE ACCESS FULL    | T_ORD |      1 |    100K|    100K|00:00:00.01 |     896 |          |
------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter(ROWNUM<=20)
   3 - filter(ROWNUM<=20)

[화면에 나온 20줄]  PAY_DT 가 모두 (null)

문제 ​

  1. 20줄이 모두 미결제 주문인 이유를 설명하시오.
  2. IX_T_ORD_PAY가 정렬을 대신하지 못하고 10만 행을 정렬하는 이유를 설명하시오.
  3. 화면의 뜻에 맞게 SQL을 고쳐 인덱스를 역순으로 20건만 읽고 멈추게 하시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자