테마
이 문제는 교재 18화 졸업 과제와 같은 이커머스 데이터베이스를 씁니다. 『튜너의 1년』을 순서대로 읽고 있다면 졸업 과제를 먼저 풀고 오세요. 아래 「테이블과 인덱스」 칸에 과제의 답 일부(제약 조건, 인덱스, 통계의 실제 상태)가 나옵니다.
마케팅팀 대시보드의 「비회원 유입」 차트는 최근 30일 동안 로그인하지 않은 방문자의 상품 조회 수를 날짜별로 그린다. 마케터 열 명의 화면이 1분마다 새로 고친다.
개발자는 회원별 「최근 본 상품」 화면용으로 만든 customer_id 인덱스를 이 차트에도 쓰려고 INDEX 힌트를 붙였지만 계획은 FULL 그대로다. 개발자는 "IS NULL은 인덱스를 못 타니 비회원을 'GUEST' 같은 값으로 채우자"고 제안했다.
product_views 상품 조회 로그: 100,000행 · 367블록 · view_id(PK) · product_id · customer_id(비회원 조회는 NULL) · view_date DATE(시분초 있음, NOT NULL)IX_PV_CUST (customer_id)(회원 화면용 · 리프 약 160블록) · 통계 최신WHERE customer_id = :c ORDER BY view_date DESC FETCH FIRST 20 ROWS ONLY(하루 수만 번)SELECT /*+ INDEX(v IX_PV_CUST) */ TRUNC(view_date) AS view_day, COUNT(*) AS guest_views
FROM product_views v
WHERE customer_id IS NULL
AND view_date >= TRUNC(:v_to) - 29
AND view_date < TRUNC(:v_to) + 1
GROUP BY TRUNC(view_date)
ORDER BY view_day
-----------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
-----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 30 |00:00:00.02 | 367 |
| 1 | SORT GROUP BY | | 1 | 30 | 30 |00:00:00.02 | 367 |
|* 2 | FILTER | | 1 | | 2548 |00:00:00.02 | 367 |
|* 3 | TABLE ACCESS FULL| PRODUCT_VIEWS | 1 | 2534 | 2548 |00:00:00.02 | 367 |
-----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter(TRUNC(:V_TO)-29<TRUNC(:V_TO)+1)
3 - filter(("CUSTOMER_ID" IS NULL AND "VIEW_DATE">=TRUNC(:V_TO)-29 AND "VIEW_DATE"<TRUNC(:V_TO)+1))
Hint Report (identified by operation id / Query Block Name / Object Alias):
Total hints for statement: 1 (U - Unused (1))
3 - SEL$1 / "V"@"SEL$1"
U - INDEX(v IX_PV_CUST)
INDEX 힌트가 쓰이지 않은 이유를 IX_PV_CUST에 무엇이 들어 있는지로 설명하시오.customer_id IS NULL이 어떻게 access 조건이 되는지 설명하시오.