테마
이 문제는 교재 18화 졸업 과제와 같은 이커머스 데이터베이스를 씁니다. 『튜너의 1년』을 순서대로 읽고 있다면 졸업 과제를 먼저 풀고 오세요. 아래 「테이블과 인덱스」 칸에 과제의 답 일부(제약 조건, 인덱스, 통계의 실제 상태)가 나옵니다.
이커머스의 상품 검색 API(Spring, MyBatis)는 카테고리와 검색어, 정렬 기준을 받아 상품을 찾는다. 세일 기간에는 초당 20번쯤 호출된다. DBA가 하드 파싱이 시간당 5만 번이라고 알렸지만, 개발팀의 답은 이랬다. "MyBatis를 쓰니까 바인드는 프레임워크가 알아서 합니다."
products: 280행 · 8블록 · PK(product_id)만 있다 · category_id, namecategories: 53행 · 4블록 · 상품은 카테고리마다 5개 남짓이다name)과 최신순(product_id DESC) 둘이고, 화면은 고른 정렬 문구를 그대로 sort 파라미터로 넘긴다.CURSOR_SHARING = EXACT<!-- ProductMapper.xml -->
<select id="search" resultType="ProductDto">
SELECT p.product_id, p.name, p.category_id
FROM products p
WHERE p.category_id = ${categoryId}
AND p.name LIKE '%${keyword}%'
ORDER BY p.${sort}
</select>
[세일 첫날 20시대 한 시간 · V$SYSSTAT 증가분]
execute count (이 API) 71,940
parse count (hard) 51,320
[그 직후 V$SQLAREA · 이 API의 부모 커서 (일부)]
SQL_ID EXECUTIONS SQL_TEXT
9x2kq0w1m3c7a 1 SELECT p.product_id, p.name, p.category_id FROM products p WHERE p.category_id = 12 AND p.name LIKE '%텀블러%' ORDER BY p.name
0f7hd2s8vb41n 1 SELECT p.product_id, p.name, p.category_id FROM products p WHERE p.category_id = 12 AND p.name LIKE '%보온병%' ORDER BY p.name
3jr6a1y0q9p2t 2 SELECT p.product_id, p.name, p.category_id FROM products p WHERE p.category_id = 31 AND p.name LIKE '%우산%' ORDER BY p.product_id DESC
…
[같은 시각 · FORCE_MATCHING_SIGNATURE로 묶은 이 API 무리]
PARENTS EXECS MB
3,410 4,020 49.6 (나머지는 이미 공유 풀에서 밀려났다)
[한 번 실행의 계획]
------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 2 |00:00:00.01 | 8 |
| 1 | SORT ORDER BY | | 1 | 1 | 2 |00:00:00.01 | 8 |
|* 2 | TABLE ACCESS FULL| PRODUCTS | 1 | 1 | 2 |00:00:00.01 | 8 |
------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter(("P"."CATEGORY_ID"=12 AND "P"."NAME" LIKE '%텀블러%'))