테마
본사 영업기획팀의 BI 도구는 시맨틱 계층의 뷰 V_SLE_DTL 하나로 판매 데이터를 본다. 사용자가 칸을 고르면 BI 도구가 그 칸만 SELECT 목록에 넣어 뷰에 SQL을 보낸다. 자주 쓰는 리포트는 아래 넷이고, Q1을 열면 1초 넘게 걸린다.
선배는 "쓰지 않는 테이블은 옵티마이저가 지우게 할 수 있어. 다만 이 DB에 무엇이 없는지부터 봐"라고 했다. 오과장은 제약을 거는 것은 좋지만 POS 판매 저장이 느려지거나 멈추면 안 된다고 했다.
V_SLE_DTL: CF11 b JOIN CF10 a ON a.SLE_NO = b.SLE_NO JOIN CF07 s ON s.SHP_NO = a.SHP_NO JOIN CF01 p ON p.ITM_NO = b.ITM_NO LEFT JOIN CF02 g ON g.CTG_NO = p.CTG_NO · 내보내는 칸: b의 칸 전부와 SLE_AMT(= SLE_QTY * SLE_UPRC), a.SLE_DT, a.SHP_NO, s.SHP_NM, p.ITM_NM, p.PTNR_NO, g.CTG_NMCF11 1,096,708행 · 8,204블록 · CF11_PK (SLE_NO, ITM_NO) / CF10 500,000행 · 4,583블록 · CF10_PK (SLE_NO) · IX_CF10_SLE_DT (SLE_DT) · SHP_NO는 NULL을 허용하지만 NULL인 행은 없다CF07 6행 · CF07_PK (SHP_NO) / CF01 109행 · CF01_PK (ITM_NO) / CF02 18행 · CF02_PK (CTG_NO)CF11.ITM_NO나 CF10.SHP_NO로 시작하는 인덱스는 없다CF01에서 지웠다) · 통계 최신-- [Q1] 상품별 누적 판매 (상품팀, 하루 40번)
SELECT ITM_NO, ITM_NM, SUM(SLE_QTY) AS qty, SUM(SLE_AMT) AS amt
FROM V_SLE_DTL
GROUP BY ITM_NO, ITM_NM;
-- [Q2] 매장별 일 매출 (영업기획, 하루 20번)
SELECT SHP_NM, SLE_DT, SUM(SLE_AMT) AS amt
FROM V_SLE_DTL
WHERE SLE_DT BETWEEN :v_from AND :v_to
GROUP BY SHP_NM, SLE_DT;
-- [Q3] 영수증 상세 (매장 POS 재출력, 하루 3,000번)
SELECT ITM_NO, ITM_NM, SLE_QTY, SLE_UPRC, SLE_AMT
FROM V_SLE_DTL
WHERE SLE_NO = :v_sle_no;
-- [Q4] 카테고리별 월 매출 (MD, 하루 60번)
SELECT CTG_NM, SUM(SLE_AMT) AS amt
FROM V_SLE_DTL
WHERE SLE_DT BETWEEN :v_from AND :v_to
GROUP BY CTG_NM;
[Q1] 상품별 누적 판매
------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Used-Mem |
------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 88 |00:00:01.12 | 12796 | |
| 1 | HASH GROUP BY | | 1 | 109 | 88 |00:00:01.12 | 12796 | 1123K (0) |
|* 2 | HASH JOIN | | 1 | 1096K | 1096K |00:00:00.98 | 12796 | 1290K (0) |
| 3 | TABLE ACCESS FULL | CF01 | 1 | 109 | 109 |00:00:00.01 | 5 | |
|* 4 | HASH JOIN | | 1 | 1096K | 1096K |00:00:00.71 | 12791 | 33M (0) |
|* 5 | HASH JOIN | | 1 | 500K | 500K |00:00:00.18 | 4587 | 1156K (0) |
| 6 | TABLE ACCESS FULL | CF07 | 1 | 6 | 6 |00:00:00.01 | 4 | |
| 7 | TABLE ACCESS FULL | CF10 | 1 | 500K | 500K |00:00:00.05 | 4583 | |
| 8 | TABLE ACCESS FULL | CF11 | 1 | 1096K | 1096K |00:00:00.09 | 8204 | |
------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("P"."ITM_NO"="B"."ITM_NO")
4 - access("A"."SLE_NO"="B"."SLE_NO")
5 - access("S"."SHP_NO"="A"."SHP_NO")
[Q3] 영수증 상세 · 판매 한 건
-------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
-------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 3 |00:00:00.01 | 16 |
| 1 | NESTED LOOPS | | 1 | 2 | 3 |00:00:00.01 | 16 |
| 2 | NESTED LOOPS | | 1 | 2 | 3 |00:00:00.01 | 10 |
| 3 | NESTED LOOPS | | 1 | 1 | 1 |00:00:00.01 | 6 |
| 4 | TABLE ACCESS BY INDEX ROWID | CF10 | 1 | 1 | 1 |00:00:00.01 | 4 |
|* 5 | INDEX UNIQUE SCAN | CF10_PK | 1 | 1 | 1 |00:00:00.01 | 3 |
| 6 | TABLE ACCESS BY INDEX ROWID | CF07 | 1 | 1 | 1 |00:00:00.01 | 2 |
|* 7 | INDEX UNIQUE SCAN | CF07_PK | 1 | 1 | 1 |00:00:00.01 | 1 |
| 8 | TABLE ACCESS BY INDEX ROWID BATCHED | CF11 | 1 | 2 | 3 |00:00:00.01 | 4 |
|* 9 | INDEX RANGE SCAN | CF11_PK | 1 | 2 | 3 |00:00:00.01 | 3 |
| 10 | TABLE ACCESS BY INDEX ROWID | CF01 | 3 | 1 | 3 |00:00:00.01 | 6 |
|* 11 | INDEX UNIQUE SCAN | CF01_PK | 3 | 1 | 3 |00:00:00.01 | 3 |
-------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
5 - access("A"."SLE_NO"=:V_SLE_NO)
7 - access("S"."SHP_NO"="A"."SHP_NO")
9 - access("B"."SLE_NO"=:V_SLE_NO)
11 - access("P"."ITM_NO"="B"."ITM_NO")
CF02가 Q1과 Q3의 계획에 이미 없는 이유도 설명하시오.RELY DISABLE NOVALIDATE로 거는 안과 비교하시오.