테마
본사 메뉴팀의 「메뉴별 판매 내역」은 메뉴 하나의 주문상품 줄을 최신순으로 한 쪽에 50줄씩 보여 준다. 메뉴팀은 그 메뉴가 몇 달 전에 어땠는지 보려고 쪽 번호를 200, 300처럼 넣고 바로 넘어간다.
쪽 번호와 화면 모양은 다음 분기 개편 때까지 바꾸지 않기로 했다. 이번 분기에는 ORD_ITEM에 인덱스를 더 만들거나 키우는 작업도 승인되지 않는다(주문상품 적재 배치의 부담 때문이다). 아래는 메뉴 하나의 200쪽(9,951 ~ 10,000번째 줄)을 열었을 때의 실행계획이다.
ORD_ITEM 주문상품: 2,472,717행 · 55,265블록 · ORD_NO · ITEM_ID · ORD_ITEM_QTY · ORD_DT · ORD_HMS · 메뉴 92개 · 메뉴 하나에 평균 약 2만 7천 줄ORD_ITEM_X03 (ITEM_ID, ORD_DT, ORD_HMS, ORD_NO): 지난 분기 이 화면용으로 만들었다. 리프 한 블록에 약 210개 항목이 들어간다. 한 메뉴의 줄은 테이블 전체에 흩어져 있어 줄마다 다른 블록에 있다(클러스터링 팩터가 행 수에 가깝다).ORD_ITEM_PK (ORD_NO, ITEM_ID)이므로 메뉴 하나 안에서는 ORD_NO가 유일하다. 오래된 블록은 대부분 버퍼 캐시에 없다. 통계는 최신이다.SELECT ORD_NO, ORD_DT, ORD_HMS, ORD_ITEM_QTY
FROM (SELECT ROWNUM rn, a.*
FROM (SELECT ORD_NO, ORD_DT, ORD_HMS, ORD_ITEM_QTY
FROM ORD_ITEM
WHERE ITEM_ID = :item
ORDER BY ORD_DT DESC, ORD_HMS DESC, ORD_NO DESC) a
WHERE ROWNUM <= :page * 50)
WHERE rn > (:page - 1) * 50
[200쪽 · :page = 200] (1쪽은 같은 모양 · A-Rows 50 · Buffers 53 · 0.01초)
-------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |
-------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 50 |00:00:00.94 | 10041 | 8873 |
|* 1 | VIEW | | 1 | 10000 | 50 |00:00:00.94 | 10041 | 8873 |
|* 2 | COUNT STOPKEY | | 1 | | 10000 |00:00:00.94 | 10041 | 8873 |
| 3 | VIEW | | 1 | 26877 | 10000 |00:00:00.93 | 10041 | 8873 |
| 4 | TABLE ACCESS BY INDEX ROWID | ORD_ITEM | 1 | 26877 | 10000 |00:00:00.93 | 10041 | 8873 |
|* 5 | INDEX RANGE SCAN DESCENDING| ORD_ITEM_X03 | 1 | 26877 | 10000 |00:00:00.01 | 51 | 0 |
-------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("RN">(:PAGE-1)*50)
2 - filter(ROWNUM<=:PAGE*50)
5 - access("ITEM_ID"=:ITEM)