테마
버거원 점주 앱의 「오늘 시간대별 주문」(IDX-022의 SQL)은 가맹점 200곳이 하루 4만 번쯤 연다. 화면이 무겁다는 민원에 지난 주말 외주 DBA가 인덱스를 손봤다. 작업 메모는 이렇다. "인덱스 개수는 늘리지 않는다. ORD_X01 맨 앞에 SHOP_NO를 넣어 다시 만들었다. 점주 앱 4블록." 월요일부터 본사 상황판 「전 매장 시간대별 주문」과 운영팀의 「점심 피크 주문 목록」이 느려졌다. 박팀장은 인덱스 개수를 늘리지 말고 셋을 다 받치는 안을 가져오라고 했다.
ORD: 1,000,000행 · 22,422블록 · 주문 일시 순으로 쌓였다 · ORD_DT VARCHAR2(8) 2012-01-01 ~ 2013-12-31 · ORD_HMS VARCHAR2(6) · SHOP_NO VARCHAR2(10) 200곳ORD_PK (ORD_NO) · ORD_X01 (SHOP_NO, ORD_DT, ORD_HMS): 지난 주말 다시 만든 것 · BLEVEL 2 · 리프 약 4,050블록(리프 한 블록에 약 250항목) · 통계 최신ORD_X01 (ORD_DT, ORD_HMS): 리프 3,774블록 · CF 22,223 · S2는 8블록, S3는 13블록이었다-- S1 점주 앱 「오늘 시간대별 주문」 (하루 약 4만 번)
SELECT SUBSTR(ORD_HMS, 1, 2) AS hh, COUNT(*) AS cnt
FROM ORD
WHERE ORD_DT = :v_dt
AND SHOP_NO = :v_shop
GROUP BY SUBSTR(ORD_HMS, 1, 2)
ORDER BY hh;
-- S2 본사 상황판 「전 매장 시간대별 주문」 (본사 PC 10대가 5분마다 · 하루 약 2,900번)
SELECT SUBSTR(ORD_HMS, 1, 2) AS hh, COUNT(*) AS cnt
FROM ORD
WHERE ORD_DT = :v_dt
GROUP BY SUBSTR(ORD_HMS, 1, 2)
ORDER BY hh;
-- S3 운영팀 「점심 피크 주문 목록」 (하루 수백 번)
SELECT ORD_NO, SHOP_NO, ORD_HMS
FROM ORD
WHERE ORD_DT = :v_dt
AND ORD_HMS BETWEEN '120000' AND '125959';
-- 지난 주말 작업
DROP INDEX ORD_X01;
CREATE INDEX ORD_X01 ON ORD (SHOP_NO, ORD_DT, ORD_HMS);
[S2 · 2013-03-15]
-----------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
-----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 14 |00:00:00.01 | 612 |
| 1 | SORT GROUP BY | | 1 | 14 | 14 |00:00:00.01 | 612 |
|* 2 | INDEX SKIP SCAN | ORD_X01 | 1 | 1370 | 1344 |00:00:00.01 | 612 |
-----------------------------------------------------------------------------------------
2 - access("ORD_DT"=:V_DT)
filter("ORD_DT"=:V_DT)
[S3 · 2013-03-15]
----------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
----------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 186 |00:00:00.01 | 618 |
| 1 | TABLE ACCESS BY INDEX ROWID BATCHED| ORD | 1 | 163 | 186 |00:00:00.01 | 618 |
|* 2 | INDEX SKIP SCAN | ORD_X01 | 1 | 163 | 186 |00:00:00.01 | 612 |
----------------------------------------------------------------------------------------------------------
2 - access("ORD_DT"=:V_DT AND "ORD_HMS">='120000' AND "ORD_HMS"<='125959')
filter(("ORD_DT"=:V_DT AND "ORD_HMS">='120000' AND "ORD_HMS"<='125959'))
[S1 · SH0042] INDEX RANGE SCAN ORD_X01 · access("SHOP_NO"=:V_SHOP AND "ORD_DT"=:V_DT) · Buffers 4
INDEX SKIP SCAN과 선두 컬럼 SHOP_NO의 종류 수로 설명하시오.