아래 상품변경이력에서 최근 1년 내에 ‘ZE367’ 상품의 변경구분코드가 ‘C2’인 최종 변경일시를 찾는 가장 효과적인 SQL을 고르시오.(단, ERD의 컬럼 나열 순서와 동일하게 PK 인덱스를 생성하였으며, 다른 인덱스는 없는 상태다)
상품변경이력_PK : [상품코드, 변경일시, 변경구분코드]
1번.
SELECT MAX(변경일시)
FROM 상품변경이력
WHERE 상품코드 = 'ZE367'
AND 변경구분코드 = 'C2'
AND 변경일시 = (SELECT MAX(변경일시)
FROM 상품변경이력
WHERE 상품번호 = 'ZE367'
AND 변경일시 >= TRUNC(ADD_MONTHS(SYSDATE, -12)));
2번.
SELECT MAX(변경일시)
FROM 상품변경이력
WHERE 상품코드 = 'ZE367'
AND 변경구분코드 = 'C2'
AND 변경일시 = (SELECT MAX(변경일시)
FROM 상품변경이력
WHERE 상품번호 = 'ZE367'
AND 변경일시 >= TRUNC(ADD_MONTHS(SYSDATE, -12))
AND 변경구분코드 = 'C2');
3번.
SELECT MAX(변경일시)
FROM 상품변경이력
WHERE 상품코드 = 'ZE367'
AND 변경일시 >= TRUNC(ADD_MONTHS(SYSDATE, -12))
AND 변경구분코드 = 'C2';
4번.
SELECT /*+ INDEX_DESC(H) */
변경일시
FROM 상품변경이력 H
WHERE 상품코드 = 'ZE367'
AND 변경일시 >= TRUNC(ADD_MONTHS(SYSDATE, -12))
AND 변경구분코드 = 'C2'
AND ROWNUM <= 1;

--AS-IS 쿼리
SELECT X.카드번호
FROM (SELECT C.카드번호, ROWNUM RNUM
FROM 주문 A
, 주문이력 B
, 결제이력 C
WHERE A.회원번호 = 'C13991'
AND A.주문상태코드 ='12'
AND B.주문번호 = A.주문번호
AND C.주문이력번호 = B.주문이력번호
ORDER BY C.결제일자 DESC
) X
WHERE RNUM = 1;
/*
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.01 | 87 |
|* 1 | VIEW | | 1 | 8 | 1 |00:00:00.01 | 87 |
| 2 | SORT ORDER BY | | 1 | 8 | 20 |00:00:00.01 | 87 |
| 3 | COUNT | | 1 | | 20 |00:00:00.01 | 87 |
| 4 | NESTED LOOPS | | 1 | | 20 |00:00:00.01 | 87 |
| 5 | NESTED LOOPS | | 1 | 8 | 20 |00:00:00.01 | 67 |
| 6 | NESTED LOOPS | | 1 | 4 | 10 |00:00:00.01 | 44 |
|* 7 | TABLE ACCESS BY INDEX ROWID| 주문 | 1 | 2 | 5 |00:00:00.01 | 22 |
|* 8 | INDEX RANGE SCAN | IX01_주문 | 1 | 20 | 19 |00:00:00.01 | 3 |
| 9 | TABLE ACCESS BY INDEX ROWID| 주문이력 | 5 | 2 | 10 |00:00:00.01 | 22 |
|* 10 | INDEX RANGE SCAN | IX01_주문이력| 5 | 2 | 10 |00:00:00.01 | 12 |
|* 11 | INDEX RANGE SCAN | IX01_결제이력| 10 | 2 | 20 |00:00:00.01 | 23 |
| 12 | TABLE ACCESS BY INDEX ROWID | 결제이력 | 20 | 2 | 20 |00:00:00.01 | 20 |
------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("RNUM"=1)
7 - filter("A"."주문상태코드"='12')
8 - access("A"."회원번호"='C13991')
10 - access("B"."주문번호"="A"."주문번호")
11 - access("C"."주문이력번호"="B"."주문이력번호")
*/
<aside> ❓ 문제
주문데이터 입력 시 최종 결제 카드번호 찾는 쿼리 입니다. 해당 쿼리를 튜닝하세요.
<aside> 💡 정답