테마
본사 레거시 유통의 「일별 판매 목록」 SQL은 세 프로그램이 같은 문자열을 복사해 쓴다. Java 본사 화면(2011), 매장 단말 프로그램(C#, ODP.NET, 2018), 경영지원팀의 리포트 도구(BI)다. 리포트 도구는 접속할 때 세션의 OPTIMIZER_MODE를 FIRST_ROWS_1로 바꾼다. 지난달 인스턴스의 CURSOR_SHARING을 EXACT로 되돌린 뒤 이 문장이 AWR 「Version Count」 상위에 올랐다.
경영지원팀은 리포트가 느리다고 하고, 본사 화면과 매장 단말은 빠르다. 박팀장이 말했다. "자식이 왜 넷인지 하나씩 가려서, 고칠 것만 고쳐 주세요."
CF10 판매: 500,000행 · 4,583블록 · SLE_NO VARCHAR2(15)는 날짜로 시작한다('20230601-0123') · SLE_NO 순(날짜순)으로 적재 · SLE_DT VARCHAR2(8) 하루 약 706건CF10_PK (SLE_NO): 리프 약 1,700블록 · IX_CF10_SLE_DT (SLE_DT): 리프 1,393블록AUTO_INVALIDATE) · 히스토그램 없음 · CURSOR_SHARING = EXACT · 바인드 피킹 켬-- 「일별 판매 목록」 (세 프로그램이 같은 문자열)
SELECT SLE_NO, SLE_HMS, SHP_NO
FROM CF10
WHERE SLE_DT = :dt
ORDER BY SLE_NO
// 매장 단말 (C#, ODP.NET)
var p = new OracleParameter("dt", OracleDbType.Varchar2);
p.Value = dt;
p.Size = 200; // "넉넉하게"
cmd.Parameters.Add(p);
-- 리포트 도구 접속 설정 (데이터 원본 초기화 SQL)
ALTER SESSION SET OPTIMIZER_MODE = FIRST_ROWS_1;
[V$SQL — 15:00 · 자식 넷]
CHILD SHAREABLE OPTIMIZER_MODE :DT MAX_LENGTH EXEC BUF/EXEC PLAN_HASH 처음 부른 곳 · 시각
0 N ALL_ROWS 32 2,104 13 1932847016 본사 화면 · 전날 09:02
1 N ALL_ROWS 32 1,388 13 1932847016 본사 화면 · 03:12
2 Y ALL_ROWS 2000 9,415 13 1932847016 매장 단말 · 07:30
3 Y FIRST_ROWS 32 612 6,285 2410375521 리포트 도구 · 09:10
[V$SQL_SHARED_CURSOR — Y인 칸 (그 줄의 자식이 새로 생긴 이유)]
child 1 : ROLL_INVALID_MISMATCH = Y
child 2 : BIND_LENGTH_UPGRADEABLE = Y
child 3 : OPTIMIZER_MODE_MISMATCH = Y
[자식 2 (ALL_ROWS) · 한 번]
-------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Used-Mem |
-------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 706 |00:00:00.01 | 13 | |
| 1 | SORT ORDER BY | | 1 | 706 | 706 |00:00:00.01 | 13 | 59392 (0)|
| 2 | TABLE ACCESS BY INDEX ROWID BATCHED| CF10 | 1 | 706 | 706 |00:00:00.01 | 13 | |
|* 3 | INDEX RANGE SCAN | IX_CF10_SLE_DT | 1 | 706 | 706 |00:00:00.01 | 4 | |
-------------------------------------------------------------------------------------------------------------------
3 - access("SLE_DT"=:DT)
[자식 3 (FIRST_ROWS_1) · 리포트 도구 한 번 · 하루치를 끝까지 받는다]
-------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Used-Mem |
-------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 706 |00:00:00.12 | 6285 | |
|* 1 | TABLE ACCESS BY INDEX ROWID | CF10 | 1 | 1 | 706 |00:00:00.12 | 6285 | |
| 2 | INDEX FULL SCAN | CF10_PK | 1 | 708 | 500K |00:00:00.04 | 1702 | |
-------------------------------------------------------------------------------------------------------------------
1 - filter("SLE_DT"=:DT)