테마
이 문제는 교재 18화 졸업 과제와 같은 이커머스 데이터베이스를 씁니다. 『튜너의 1년』을 순서대로 읽고 있다면 졸업 과제를 먼저 풀고 오세요. 아래 「테이블과 인덱스」 칸에 과제의 답 일부(제약 조건, 인덱스, 통계의 실제 상태)가 나옵니다.
마케팅팀의 「구매 직전 조회 상품」 분석은 주문마다 그 고객이 주문하기 전에 마지막으로 본 상품을 붙여, 마지막으로 본 상품을 실제로 산 비율을 낸다. 담당자가 달을 바꿔 가며 돌리고, 한 번에 2.4초가 걸린다. 결과 건수가 그달 주문 수와 다르다는 것도 문제다. 2024년 6월은 주문이 583건인데 결과는 569행이다. 담당자는 "빠진 14건은 어디로 갔는지 모르겠다"라고 한다.
orders: 34,908행 · 193블록 · PK(order_id)만 있음 · order_date DATE(시분초 있음) · 2024년 6월 583건(고객 561명)product_views: 100,000행 · 367블록 · PK(view_id)만 있음 · customer_id는 비회원 조회면 NULL(약 20%) · view_date DATE(시분초 있음) · 회원 조회는 고객 한 명에 평균 15건customer_id에 인덱스가 없다 · 인덱스는 승인 절차를 거쳐야 만들 수 있다 · 통계 최신SELECT o.order_id, o.customer_id, o.order_date,
v.product_id AS last_view_pid, v.view_date AS last_view_date
FROM orders o, product_views v
WHERE o.order_date >= TO_DATE(:v_from, 'YYYYMMDD')
AND o.order_date < TO_DATE(:v_to, 'YYYYMMDD')
AND v.customer_id = o.customer_id
AND v.view_date = (SELECT MAX(x.view_date)
FROM product_views x
WHERE x.customer_id = o.customer_id
AND x.view_date <= o.order_date)
---------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
---------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 569 |00:00:02.41 | 214K|
|* 1 | FILTER | | 1 | | 569 |00:00:02.41 | 214K|
|* 2 | HASH JOIN | | 1 | 2230 | 8812 |00:00:00.04 | 560 |
|* 3 | TABLE ACCESS FULL| ORDERS | 1 | 583 | 583 |00:00:00.01 | 193 |
|* 4 | TABLE ACCESS FULL| PRODUCT_VIEWS | 1 | 80000 | 80000 |00:00:00.02 | 367 |
| 5 | SORT AGGREGATE | | 583 | 1 | 583 |00:00:02.36 | 213K|
|* 6 | TABLE ACCESS FULL| PRODUCT_VIEWS | 583 | 8 | 4664 |00:00:02.35 | 213K|
---------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("V"."VIEW_DATE"=)
2 - access("V"."CUSTOMER_ID"="O"."CUSTOMER_ID")
3 - filter(("O"."ORDER_DATE">=TO_DATE(:V_FROM,'YYYYMMDD') AND "O"."ORDER_DATE"<TO_DATE(:V_TO,'YYYYMMDD')))
4 - filter("V"."CUSTOMER_ID" IS NOT NULL)
6 - filter(("X"."CUSTOMER_ID"=:B1 AND "X"."VIEW_DATE"<=:B2))
Starts로 설명하고, 결과에서 14건이 빠진 까닭도 쓰시오.product_views (customer_id, view_date) 인덱스를 만들고 주문마다 한 건에서 멈추는 안과 견주어, 이 분석에는 어느 쪽이 맞는지 숫자로 쓰시오.