테마
한빛유통 고객센터는 고객이 불러 주는 주문번호(HB-20240615-0012345 모양)로 주문을 찾는다. 주문번호는 저장된 칸이 아니라 주문일자와 주문 순번을 이어 붙인 표기다. 지난달 개발팀이 표기 함수 FN_ORD_NO를 만들고 그 함수로 함수 기반 인덱스를 만들었다.
체인 ①(T_ORD_BIG 재적재)은 14화 이후 인덱스를 끄고 직접 경로로 넣은 뒤 다시 짓는데, 새 인덱스도 그 순서에 넣었다. 그 뒤로 체인 ①이 5.0초에서 21.9초가 됐다. 오과장: "인덱스 하나를 더 지었을 뿐인데 다른 두 인덱스를 합친 것의 세 배가 넘게 걸려요."
T_ORD_BIG: 1,000,000행 · 5,826블록 · ORD_SEQ 1 ~ 1,000,000(유일) · ORD_DT 전부 자정 · 체인 ①이 끝난 뒤에만 화면이 읽고, 낮에는 고치는 일이 없다.IX_ORD_BIG_DT_AMT (ORD_DT, ORD_AMT) · IX_ORD_BIG_DT_SEQ (ORD_DT, ORD_SEQ) · 지난달 만든 IX_ORD_BIG_ORDNO_FX (FN_ORD_NO(ORD_DT, ORD_SEQ))FN_ORD_NO: PL/SQL 함수 · DETERMINISTIC · 테이블을 읽지 않고 'HB-' || 주문일자(YYYYMMDD) || '-' || 순번 7자리를 돌려준다.-- 지난달 개발팀
CREATE OR REPLACE FUNCTION FN_ORD_NO(p_dt DATE, p_seq NUMBER)
RETURN VARCHAR2 DETERMINISTIC IS
BEGIN
RETURN 'HB-' || TO_CHAR(p_dt, 'YYYYMMDD') || '-' || LPAD(p_seq, 7, '0');
END;
CREATE INDEX IX_ORD_BIG_ORDNO_FX ON T_ORD_BIG (FN_ORD_NO(ORD_DT, ORD_SEQ));
-- 고객센터 「주문번호로 찾기」
SELECT ORD_SEQ, CUS_ID, ORD_DT, ORD_ST, ORD_AMT
FROM T_ORD_BIG
WHERE FN_ORD_NO(ORD_DT, ORD_SEQ) = :v_ord_no;
-- 체인 ① 끝부분 (14화 이후 순서에 한 줄을 더했다)
ALTER INDEX IX_ORD_BIG_DT_AMT REBUILD;
ALTER INDEX IX_ORD_BIG_DT_SEQ REBUILD;
ALTER INDEX IX_ORD_BIG_ORDNO_FX REBUILD;
[고객센터 「주문번호로 찾기」]
------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.01 | 4 |
| 1 | TABLE ACCESS BY INDEX ROWID| T_ORD_BIG | 1 | 1 | 1 |00:00:00.01 | 4 |
|* 2 | INDEX RANGE SCAN | IX_ORD_BIG_ORDNO_FX | 1 | 1 | 1 |00:00:00.01 | 3 |
------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("SQLP"."FN_ORD_NO"("ORD_DT","ORD_SEQ")=:V_ORD_NO)
[체인 ① 단계별 — 연습 DB 복사본]
단계 경과 CPU PL/SQL 함수 호출
TRUNCATE · UNUSABLE · APPEND 적재 0.3 초 0.2 초 0
REBUILD IX_ORD_BIG_DT_AMT 2.4 초 2.1 초 0
REBUILD IX_ORD_BIG_DT_SEQ 2.3 초 2.0 초 0
REBUILD IX_ORD_BIG_ORDNO_FX 16.9 초 16.2 초 1,000,000
합계 21.9 초 (지난달 5.0 초)
[REBUILD IX_ORD_BIG_ORDNO_FX — 세션 통계]
PL/SQL execution elapsed time 11.4 초
sorts (rows) 1,000,000
리프 블록 약 4,370 (키 19바이트 + ROWID)