테마
버거원 본사 대시보드의 「매장 순위」는 오픈 이후 누적 주문 수로 매장 순위를 매기고, 맨 아래에 '매장 미확인' 줄을 따로 보여 준다. 대시보드는 10분마다 새로 고친다.
조민우는 "매장 인덱스가 있는데 왜 테이블을 읽냐"며 WHERE SHOP_NO IS NOT NULL을 붙였다. 인덱스만 읽게 되어 빨라졌지만 '매장 미확인' 줄이 사라졌다.
ORD: 1,000,000행 · 22,422블록(전체 스캔 22,239) · ORD_NO NUMBER(PK)ORD_DT VARCHAR2(8) · ORD_HMS VARCHAR2(6) · SHOP_NO VARCHAR2(10): 세 컬럼 모두 NOT NULL 제약이 없다(적재 스크립트의 DDL 그대로)ORD_DT와 ORD_HMS의 실제 NULL은 0건이다. SHOP_NO는 2013-03-02 ~ 03-05 키오스크 장애 때 매장 번호 없이 들어온 주문 1,204건이 NULL이다
(문제 설정: 교재의 ORD에는 SHOP_NO가 빈 행이 없다)ORD_PK (ORD_NO): 리프 약 2,090 · ORD_X01 (ORD_DT, ORD_HMS): 리프 3,774 · IX_ORD_SHOP_DT (SHOP_NO, ORD_DT): 리프 3,310 · 통계 최신-- [원본]
SELECT SHOP_NO, COUNT(*) AS ord_cnt
FROM ORD
GROUP BY SHOP_NO
ORDER BY ord_cnt DESC;
-- [조민우의 수정안]
SELECT SHOP_NO, COUNT(*) AS ord_cnt
FROM ORD
WHERE SHOP_NO IS NOT NULL
GROUP BY SHOP_NO
ORDER BY ord_cnt DESC;
[원본]
--------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
--------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 201 |00:00:00.21 | 22239 |
| 1 | SORT ORDER BY | | 1 | 200 | 201 |00:00:00.21 | 22239 |
| 2 | HASH GROUP BY | | 1 | 200 | 201 |00:00:00.21 | 22239 |
| 3 | TABLE ACCESS FULL | ORD | 1 | 1000K| 1000K|00:00:00.12 | 22239 |
--------------------------------------------------------------------------------------------------
[조민우의 수정안]
--------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
--------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 200 |00:00:00.09 | 3318 |
| 1 | SORT ORDER BY | | 1 | 200 | 200 |00:00:00.09 | 3318 |
| 2 | HASH GROUP BY | | 1 | 200 | 200 |00:00:00.09 | 3318 |
|* 3 | INDEX FAST FULL SCAN| IX_ORD_SHOP_DT | 1 | 999K| 999K|00:00:00.05 | 3318 |
--------------------------------------------------------------------------------------------------
3 - filter("SHOP_NO" IS NOT NULL)
IX_ORD_SHOP_DT가 있는데도 원본이 테이블 전체를 읽는 이유를 설명하시오. ORD_DT의 실제 NULL이 0건인데도 그렇게 되는 이유도 설명하시오.