테마
본사 상황실의 「전 매장 오늘 현황」은 매장 200곳의 오늘 주문 건수와 마지막 주문 시각을 1분마다 새로 띄운다(영업시간 14시간 동안 하루 840번). 주문이 없는 매장도 0으로 보여야 해서 아우터 조인으로 썼다. 개발자는 "NL 조인이니 오늘 주문 1,400건을 하나씩 읽으면서 매장을 붙일 줄 알았다"라고 한다. 아래는 2013-06-14 밤 9시에 뜬 실행계획이다.
SHOP 매장: 200행 · 5블록 · PK (SHOP_NO)ORD 주문: 1,000,000행 · 22,422블록 · 하루 약 1,370건ORD_X01 (ORD_DT, ORD_HMS): 날짜순 적재, CF 22,223 · 하루치는 인덱스 리프 약 6블록, 테이블 약 31블록SHOP_NO로 시작하는 인덱스는 없다 · 2013-06-14 주문 1,368건 · 그날 주문이 없는 매장 3곳(리모델링) · 통계 최신SELECT /*+ USE_NL(o) */ -- 주문은 NL 로 붙인다 (오늘 주문부터 읽게)
s.SHOP_NO, s.SHOP_NM,
COUNT(o.ORD_NO) AS ord_cnt,
MAX(o.ORD_HMS) AS last_hms
FROM SHOP s, ORD o
WHERE o.SHOP_NO(+) = s.SHOP_NO
AND o.ORD_DT(+) = :v_dt
GROUP BY s.SHOP_NO, s.SHOP_NM
ORDER BY s.SHOP_NO
-----------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
-----------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 200 |00:00:00.19 | 7609 |
| 1 | SORT GROUP BY | | 1 | 200 | 200 |00:00:00.19 | 7609 |
| 2 | NESTED LOOPS OUTER | | 1 | 1370 | 1371 |00:00:00.18 | 7609 |
| 3 | TABLE ACCESS FULL | SHOP | 1 | 200 | 200 |00:00:00.01 | 7 |
|* 4 | TABLE ACCESS BY INDEX ROWID BATCHED| ORD | 200 | 7 | 1368 |00:00:00.17 | 7602 |
|* 5 | INDEX RANGE SCAN | ORD_X01 | 200 | 1370 | 274K|00:00:00.04 | 1200 |
-----------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - filter("O"."SHOP_NO"(+)="S"."SHOP_NO")
5 - access("O"."ORD_DT"(+)=:V_DT)
ORD (SHOP_NO, ORD_DT) 인덱스를 만들어 NL을 유지하는 안과 숫자로 비교하시오.