테마
본사 회계팀은 매달 초 「월간 판매 내려받기」로 지난달 판매 전표를 파일로 받는다. 매장명은 공통 함수 FN_SHP_NM이 붙이는데, 이 함수는 화면 40여 곳이 함께 쓰고 있어서 개발팀은 함수를 고치기를 꺼린다.
DBA가 내려받기 한 번의 세션 통계를 보내왔다. "전표는 2만 건인데 recursive calls도 2만 번이다. 매장은 다섯 곳뿐인데."
CF10 판매: 500,000행 · 4,583블록 · SLE_DT VARCHAR2(8) · 2023년 12월 20,864건 · 판매 매장은 5곳(SHP_NO 1001 ~ 1005)IX_CF10_SLE_DT (SLE_DT): 이 문제에서는 있다 · 통계 최신CF07 매장: 6행(본사 1000과 매장 5곳) · 4블록 · CF07_PK (SHP_NO)dep=1).CREATE OR REPLACE FUNCTION FN_SHP_NM(p_shp_no NUMBER) RETURN VARCHAR2 IS
v_nm CF07.SHP_NM%TYPE;
BEGIN
SELECT SHP_NM INTO v_nm FROM CF07 WHERE SHP_NO = p_shp_no;
RETURN v_nm;
END;
/
SELECT h.SLE_NO, h.SLE_DT, h.SLE_HMS, h.SHP_NO,
FN_SHP_NM(h.SHP_NO) AS shp_nm
FROM CF10 h
WHERE h.SLE_DT BETWEEN '20231201' AND '20231231';
[DISPLAY_CURSOR (ALLSTATS LAST)]
------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 20864 |00:00:00.24 | 295 |
| 1 | TABLE ACCESS BY INDEX ROWID BATCHED| CF10 | 1 | 20833 | 20864 |00:00:00.02 | 295 |
|* 2 | INDEX RANGE SCAN | IX_CF10_SLE_DT | 1 | 20833 | 20864 |00:00:00.01 | 98 |
------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("H"."SLE_DT">='20231201' AND "H"."SLE_DT"<='20231231')
[세션 통계: 내려받기 한 번 (V$MYSTAT 증가분)]
경과 시간 0.24 초
recursive calls 20,871
execute count 20,866
session logical reads 42,023
[V$SQL: 함수 안의 문장 (dep=1)]
SELECT SHP_NM FROM CF07 WHERE SHP_NO = :B1 EXECUTIONS 20,864 · ROWS 20,864 · BUFFER_GETS 41,728 (한 번에 2블록)