테마
버거원 본사는 매일 23시 30분에 일 마감 프로시저를 돌려 매장마다 그날 주문 수를 SHOP_DAY_CLOSE에 쌓는다. 매장 코드는 옛 POS에서 숫자(1 ~ 200)였고, 프로시저는 그 시절 루프를 그대로 쓴다.
가맹점이 늘면서 마감 시각이 밀린다며 오과장이 TKPROF를 떠 왔다. 아래는 2013년 3월 15일 마감분이다.
ORD: 1,000,000행 · 22,422블록 · 주문 일시 순으로 쌓였다 · SHOP_NO VARCHAR2(10) 'SH0001' ~ 'SH0200'(200곳에 고르게) · ORD_DT VARCHAR2(8)SHOP: 200행 · 5블록 · PK SHOP_PK (SHOP_NO)ORD_X02 (SHOP_NO, ORD_DT): 가맹점주 앱용 · BLEVEL 2 · 리프 약 3,100블록 · ORD_X01 (ORD_DT, ORD_HMS) · 통계 최신SHOP_DAY_CLOSE (SHOP_NO, CLOSE_DT, ORD_CNT): 하루 200행씩 쌓는 마감 테이블 · 인덱스 없음PROCEDURE P_DAY_CLOSE(p_dt VARCHAR2) IS
v_cnt NUMBER;
BEGIN
FOR i IN 1 .. 200 LOOP
SELECT COUNT(*) INTO v_cnt
FROM ORD
WHERE TO_NUMBER(SUBSTR(SHOP_NO, 3)) = i
AND ORD_DT = p_dt;
INSERT INTO SHOP_DAY_CLOSE (SHOP_NO, CLOSE_DT, ORD_CNT)
VALUES ('SH' || LPAD(i, 4, '0'), p_dt, v_cnt);
END LOOP;
COMMIT;
END;
[TKPROF — 루프 안의 SELECT]
SELECT COUNT(*) FROM ORD WHERE TO_NUMBER(SUBSTR(SHOP_NO, 3)) = :B2 AND ORD_DT = :B1
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 200 0.01 0.01 0 0 0 0
Fetch 200 1.02 1.05 0 122400 0 200
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 401 1.03 1.06 0 122400 0 200
[DBMS_XPLAN — 마지막 한 번 (i = 200)]
----------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.01 | 612 |
| 1 | SORT AGGREGATE | | 1 | 1 | 1 |00:00:00.01 | 612 |
|* 2 | INDEX SKIP SCAN| ORD_X02 | 1 | 1 | 7 |00:00:00.01 | 612 |
----------------------------------------------------------------------------------------
2 - access("ORD_DT"=:B1)
filter(("ORD_DT"=:B1 AND TO_NUMBER(SUBSTR("SHOP_NO",3))=:B2))