테마
이 문제는 교재 18화 졸업 과제와 같은 이커머스 데이터베이스를 씁니다. 『튜너의 1년』을 순서대로 읽고 있다면 졸업 과제를 먼저 풀고 오세요. 아래 「테이블과 인덱스」 칸에 과제의 답 일부(제약 조건, 인덱스, 통계의 실제 상태)가 나옵니다.
마케팅팀의 「적립 지연 점검」은 한 달 치 주문마다, 같은 고객에게 주문 뒤 10분 안에 들어온 적립(EARN) 거래를 붙여 본다. 화면은 이 목록과 주문 수를 비교해 적립이 늦거나 빠진 주문을 따로 띄운다. 포인트 거래에는 주문 번호가 없어서 고객과 시각으로 짝을 짓는다.
SQL 위에는 -- 기간(부등호) 조건 조인은 해시 조인이 안 된다. NL 로 고정이라는 주석이 있다. 담당자가 기간을 바꿔 가며 하루 수십 번 돌린다. 아래는 2024년 6월(주문 583건)의 실행계획이다.
orders: 34,908행 · 193블록 · PK(order_id)만 있음 · order_date 시분초 있음 · 2024년 6월 583건point_transactions: 45,000행 · 210블록 · PK(tx_id)만 있음 · tx_type EARN 15,000건 · USE · EXPIRE · created_at 시분초 있음customer_id에 인덱스가 없다 (FK는 꺼져 있다) · 통계 최신SELECT /*+ LEADING(o p) USE_NL(p) */
o.order_id, o.customer_id, o.order_date, p.tx_id, p.amount, p.created_at
FROM orders o, point_transactions p
WHERE o.order_date >= TO_DATE(:v_from, 'YYYYMMDD')
AND o.order_date < TO_DATE(:v_to, 'YYYYMMDD')
AND p.customer_id = o.customer_id
AND p.tx_type = 'EARN'
AND p.created_at >= o.order_date
AND p.created_at < o.order_date + 10/1440
-----------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
-----------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 521 |00:00:00.38 | 122K |
|* 1 | FILTER | | 1 | | 521 |00:00:00.38 | 122K |
| 2 | NESTED LOOPS | | 1 | 2 | 521 |00:00:00.38 | 122K |
|* 3 | TABLE ACCESS FULL| ORDERS | 1 | 573 | 583 |00:00:00.01 | 193 |
|* 4 | TABLE ACCESS FULL| POINT_TRANSACTIONS | 583 | 1 | 521 |00:00:00.37 | 122K |
-----------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(TO_DATE(:V_TO,'YYYYMMDD')>TO_DATE(:V_FROM,'YYYYMMDD'))
3 - filter(("O"."ORDER_DATE">=TO_DATE(:V_FROM,'YYYYMMDD') AND "O"."ORDER_DATE"<TO_DATE(:V_TO,'YYYYMMDD')))
4 - filter(("P"."CUSTOMER_ID"="O"."CUSTOMER_ID" AND "P"."TX_TYPE"='EARN' AND "P"."CREATED_AT">="O"."ORDER_DATE"
AND "P"."CREATED_AT"<"O"."ORDER_DATE"+.006944444444444444444444444444444444444444))
Starts와 블록 수로 설명하시오.