테마
지난달 03시에 배치 하나가 ORA-01652로 멈춘 뒤, DBA는 "힙 테이블은 넣은 순서를 약속하지 않으니 적재 SELECT의 ORDER BY는 정렬만 늘린다"며 야간 INSERT … SELECT에서 ORDER BY를 일괄로 지우는 정리안을 올렸다. 목록에는 MD팀의 분석 사본 CF11_ANL을 채우는 적재도 들어 있다.
정리안을 개발 서버에 먼저 넣고 다음 날 아침 MD팀 화면을 재 보니, 「메뉴별 일 판매 추이」가 메뉴 하나 한 해에 81블록이던 것이 3,689블록이 됐다. MD팀 20명이 하루 약 1,500번 여는 화면이다. 적재 SQL의 ORDER BY 옆에는 아무 주석도 없다.
CF10 판매: 500,000행 · 4,583블록 / CF11 판매상품: 1,096,708행 · 8,204블록 · 둘 다 판매번호(곧 판매일) 순으로 쌓여 있다CF11_ANL 분석 사본(이 문제에서 쓰는 표): ITM_NO · SLE_DT · SLE_NO · SHP_NO · SLE_QTY · SLE_UPRC · 1,096,708행 · 10,240블록(블록당 약 107행) · 03:00에 TRUNCATE한 뒤 APPEND로 다시 채운다 · MD팀 화면만 읽는다CF11_ANL_X01 (ITM_NO, SLE_DT): 리프 약 3,100블록 · CLUSTERING_FACTOR는 운영 10,262, 정리안대로 적재한 개발 서버 641,880-- 정리안 : 03:00 분석 사본 적재에서 ORDER BY d.ITM_NO, h.SLE_DT, d.SLE_NO 를 지운 판
INSERT /*+ APPEND */ INTO CF11_ANL (ITM_NO, SLE_DT, SLE_NO, SHP_NO, SLE_QTY, SLE_UPRC)
SELECT d.ITM_NO, h.SLE_DT, d.SLE_NO, h.SHP_NO, d.SLE_QTY, d.SLE_UPRC
FROM CF10 h, CF11 d
WHERE d.SLE_NO = h.SLE_NO;
-- MD 「메뉴별 일 판매 추이」
SELECT SLE_DT, SUM(SLE_QTY) AS QTY, SUM(SLE_QTY * SLE_UPRC) AS AMT
FROM CF11_ANL
WHERE ITM_NO = :itm
AND SLE_DT BETWEEN :d_from AND :d_to
GROUP BY SLE_DT
ORDER BY SLE_DT;
[운영 · 지금 적재 (ORDER BY 있음) · 03:00]
-----------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem | Used-Tmp|
-----------------------------------------------------------------------------------------------------------------------------------------
| 0 | INSERT STATEMENT | | 1 | | 0 |00:00:09.62 | 13204 | | | | |
| 1 | LOAD AS SELECT | CF11_ANL | 1 | | 0 |00:00:09.62 | 13204 | | | | |
| 2 | OPTIMIZER STATISTICS GATHERING | | 1 | 1096K| 1096K|00:00:07.84 | 12787 | | | | |
| 3 | SORT ORDER BY | | 1 | 1096K| 1096K|00:00:07.61 | 12787 | 81M| 3961K| 20M (1)| 67M|
|* 4 | HASH JOIN | | 1 | 1096K| 1096K|00:00:00.71 | 12787 | 19M| 3412K| 19M (0)| |
| 5 | TABLE ACCESS FULL | CF10 | 1 | 500K| 500K|00:00:00.05 | 4583 | | | | |
| 6 | TABLE ACCESS FULL | CF11 | 1 | 1096K| 1096K|00:00:00.12 | 8204 | | | | |
-----------------------------------------------------------------------------------------------------------------------------------------
4 - access("D"."SLE_NO"="H"."SLE_NO")
[운영 · MD 화면 · 카페모카 2023년 한 해 (6,183줄)]
---------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
---------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 365 |00:00:00.01 | 81 |
| 1 | SORT GROUP BY NOSORT | | 1 | 365 | 365 |00:00:00.01 | 81 |
|* 2 | FILTER | | 1 | | 6183 |00:00:00.01 | 81 |
| 3 | TABLE ACCESS BY INDEX ROWID| CF11_ANL | 1 | 6200 | 6183 |00:00:00.01 | 81 |
|* 4 | INDEX RANGE SCAN | CF11_ANL_X01 | 1 | 6200 | 6183 |00:00:00.01 | 21 |
---------------------------------------------------------------------------------------------------------
[개발 서버 · 정리안대로 적재한 뒤 · 같은 메뉴, 같은 기간]
---------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
---------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 365 |00:00:00.09 | 3689 |
| 1 | SORT GROUP BY NOSORT | | 1 | 365 | 365 |00:00:00.09 | 3689 |
|* 2 | FILTER | | 1 | | 6183 |00:00:00.09 | 3689 |
| 3 | TABLE ACCESS BY INDEX ROWID| CF11_ANL | 1 | 6200 | 6183 |00:00:00.09 | 3689 |
|* 4 | INDEX RANGE SCAN | CF11_ANL_X01 | 1 | 6200 | 6183 |00:00:00.01 | 21 |
---------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter(:D_FROM<=:D_TO)
4 - access("ITM_NO"=:ITM AND "SLE_DT">=:D_FROM AND "SLE_DT"<=:D_TO)
CF11_ANL_X01의 CLUSTERING_FACTOR와 적재 SQL로 설명하시오.