테마
10화에서 본사에 보낸 「통계 수집 정책서」 후보에 유통지원팀이 회신했다. "분석 패키지는 업체 소스라 SQL을 고칠 수 없습니다. 통계 처방은 원본에 걸어도 좋습니다. 단, 무엇이 바뀌는지 목록과 되돌리는 방법을 함께 주세요."
패키지의 리포트들은 아래 세 SQL의 결과 위에서 조인 방법과 순서를 정한다. 선배는 셋의 E-Rows를 손으로 맞혀 보고 처방을 한 묶음으로 고르라고 했다.
CF10 판매: 500,000행 · 4,583블록 · SLE_DT VARCHAR2(8) · SHP_NO 매장 5곳(1001 ~ 1005, 곳마다 약 10만 건) · REG_EMP_NO 등록 직원(schemas 표에는 없는 열이다. 매장마다 직원 한 명이 등록하고, 직원 번호가 매장 번호와 같다) · 2023년 6월 판매 20,953건CF11 판매상품: 1,096,708행 · 8,204블록 · ITM_NO 88종(1001이 275,135줄로 가장 많고, 가장 적은 상품은 3,032줄) · SLE_UPRC 단가 11종 · 상품마다 단가가 하나다(1001의 단가는 2,500원, 2,500원 판매는 모두 533,248줄)CF10_PK (SLE_NO) · CF11_PK (SLE_NO, ITM_NO) · IX_CF10_SLE_DT (SLE_DT)CF10 선호도 FOR ALL COLUMNS SIZE 1 · CF11 선호도 FOR ALL COLUMNS SIZE 1 FOR COLUMNS SIZE 254 SLE_UPRC(SLE_UPRC만 FREQUENCY 히스토그램) · 확장 통계 없음-- (가) 매장 · 등록 직원별 판매 (점장 화면)
SELECT COUNT(*), MIN(SLE_DT), MAX(SLE_DT)
FROM CF10
WHERE SHP_NO = 1003
AND REG_EMP_NO = 1003;
-- (나) 상품 · 단가별 판매 (MD 화면)
SELECT SUM(SLE_QTY), SUM(SLE_QTY * SLE_UPRC)
FROM CF11
WHERE ITM_NO = 1001
AND SLE_UPRC = 2500;
-- (다) 월 판매 (BI 차트 · 판매일자를 날짜로 바꿔 묻는다)
SELECT SHP_NO, COUNT(*)
FROM CF10
WHERE TO_DATE(SLE_DT, 'YYYYMMDD') >= DATE '2023-06-01'
AND TO_DATE(SLE_DT, 'YYYYMMDD') < DATE '2023-07-01'
GROUP BY SHP_NO;
[(가)]
------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.05 | 4583 |
| 1 | SORT AGGREGATE | | 1 | 1 | 1 |00:00:00.05 | 4583 |
|* 2 | TABLE ACCESS FULL| CF10 | 1 | 20000 | 100K |00:00:00.04 | 4583 |
------------------------------------------------------------------------------------
2 - filter(("SHP_NO"=1003 AND "REG_EMP_NO"=1003))
[(나)]
------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.08 | 8204 |
| 1 | SORT AGGREGATE | | 1 | 1 | 1 |00:00:00.08 | 8204 |
|* 2 | TABLE ACCESS FULL| CF11 | 1 | 6060 | 275K |00:00:00.07 | 8204 |
------------------------------------------------------------------------------------
2 - filter(("ITM_NO"=1001 AND "SLE_UPRC"=2500))
[(다)]
------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 5 |00:00:00.09 | 4583 |
| 1 | HASH GROUP BY | | 1 | 5 | 5 |00:00:00.09 | 4583 |
|* 2 | TABLE ACCESS FULL| CF10 | 1 | 1250 | 20953 |00:00:00.08 | 4583 |
------------------------------------------------------------------------------------
2 - filter((TO_DATE("SLE_DT",'YYYYMMDD')>=TO_DATE(' 2023-06-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND
TO_DATE("SLE_DT",'YYYYMMDD')<TO_DATE(' 2023-07-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss')))
정확한 A-Rows : (가) 100,167 · (나) 275,135 · (다) 20,953
E-Rows(20,000 · 6,060 · 1,250)를 손으로 계산하고, 옵티마이저가 각각 무엇을 잘못 가정했는지 쓰시오.