테마
버거 본사의 「매장 묶음 시간대 분석」 화면은 사용자가 매장을 고르면(1곳 ~ 200곳) 매장 번호를 전역 임시 테이블 GT_SHOP_PICK에 넣고 아래 SQL을 실행한다. 연도는 화면이 리터럴로 넣고, 바인드 변수는 없다. 사용자는 점장, 지역장, 본부장 약 30명이고 하루 약 400번 쓴다.
박팀장이 전했다. "본부장님이 150곳을 고르면 어떤 날은 바로 뜨고 어떤 날은 3초가 넘는답니다." 조민우가 공유 풀을 보니 느린 날의 커서는 그날 08:40에 한 점장이 매장 한 곳을 골라 하드 파싱한 것이었다.
GT_SHOP_PICK: 전역 임시 테이블(ON COMMIT PRESERVE ROWS) · SHOP_NO VARCHAR2(6) · 세션마다 1 ~ 200행 · 통계 없음(아무도 모으지 않았다) · GLOBAL_TEMP_TABLE_STATS는 기본값 SESSIONORD: 1,000,000행 · 22,422블록 · 2013년 500,218행 · 매장당 한 해 약 2,500행 · 날짜순 적재ORD_PK (ORD_NO) · ORD_X01 (ORD_DT, ORD_HMS) · ORD_X02 (SHOP_NO, ORD_DT)(클러스터링 팩터 약 99만, 한 매장의 주문은 테이블 곳곳에 흩어져 있다)optimizer_dynamic_sampling 2(기본값)-- 화면 : INSERT INTO GT_SHOP_PICK (SHOP_NO) VALUES (...) 를 고른 매장 수만큼 · 그다음
SELECT o.SHOP_NO, SUBSTR(o.ORD_HMS, 1, 2) AS hh, COUNT(*) AS ord_cnt
FROM GT_SHOP_PICK g, ORD o
WHERE o.SHOP_NO = g.SHOP_NO
AND o.ORD_DT BETWEEN '20130101' AND '20131231'
GROUP BY o.SHOP_NO, SUBSTR(o.ORD_HMS, 1, 2)
[느린 날 10:05 · 본부장 150곳 · 커서는 08:40 점장(1곳)이 하드 파싱한 것]
---------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
---------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 2400 |00:00:03.12 | 378K|
| 1 | HASH GROUP BY | | 1 | 2501 | 2400 |00:00:03.12 | 378K|
| 2 | NESTED LOOPS | | 1 | 2501 | 375K|00:00:02.96 | 378K|
| 3 | NESTED LOOPS | | 1 | 2501 | 375K|00:00:00.61 | 1653 |
| 4 | TABLE ACCESS FULL | GT_SHOP_PICK | 1 | 1 | 150 |00:00:00.01 | 3 |
|* 5 | INDEX RANGE SCAN | ORD_X02 | 150 | 2501 | 375K|00:00:00.42 | 1650 |
| 6 | TABLE ACCESS BY INDEX ROWID| ORD | 375K| 1 | 375K|00:00:02.18 | 376K|
---------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
5 - access("O"."SHOP_NO"="G"."SHOP_NO" AND "O"."ORD_DT">='20130101' AND "O"."ORD_DT"<='20131231')
Note
-----
- dynamic statistics used: dynamic sampling (level=2)
[빠른 날 · 그날 첫 사용자가 지역장(120곳)이었다]
---------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
---------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 2400 |00:00:00.21 | 22425 |
| 1 | HASH GROUP BY | | 1 | 2856 | 2400 |00:00:00.21 | 22425 |
|* 2 | HASH JOIN | | 1 | 300K| 375K|00:00:00.17 | 22425 |
| 3 | TABLE ACCESS FULL| GT_SHOP_PICK | 1 | 120 | 150 |00:00:00.01 | 3 |
|* 4 | TABLE ACCESS FULL| ORD | 1 | 500K| 500K|00:00:00.09 | 22422 |
---------------------------------------------------------------------------------------
[같은 두 계획을 점장(1곳)이 쓰면] NL 계획 Buffers 2,515 · 0.02초 / 해시 계획 Buffers 22,425 · 0.15초