테마
버거원 본사는 매주 일요일 03시에 「연간 상품 판매 순위」 마트를 2013년 치로 다시 적재한다. 적재 SQL에는 2019년에 붙인 FULL(oi) PARALLEL(oi 8) 힌트가 있다.
지난 일요일, 같은 시간에 도는 매출 집계 배치 두 개가 병렬 서버를 얻지 못해 직렬로 강등되었고(Parallel operations downgraded to serial), 03시 배치 묶음 전체가 40분 늦게 끝났다. 배치 담당 오과장은 이렇게 물었다. "병렬도를 4로 낮추면 되나?"
ORD_ITEM 주문상품: 2,472,717행 · 55,265블록(문자열 채움 컬럼 때문에 행이 넓어 블록당 약 45행) · ORD_DT VARCHAR2(8) 2012 ~ 2013 · 2013년 약 1,236,000행 · ITEM_ID 92종 · ORD_NO와 ITEM_ID는 PK 컬럼이라 NOT NULLORD_ITEM_PK (ORD_NO, ITEM_ID) · ORD_ITEM_X01 (ORD_DT, ORD_HMS) · ORD_ITEM_X02 (ITEM_ID, ORD_DT, ORD_ITEM_QTY): X02는 「상품 월간 추이」용으로 2019년 뒤에 만들었다 · BLEVEL 2 · 리프 약 8,500블록(리프 한 블록에 약 290항목) · 통계 최신ITEM_SALE_YEAR 연간 상품 판매 마트(이 문제에서 쓰는 집계 테이블): SALE_YY · ITEM_ID · QTY · LINE_CNT · 해마다 92행 · 적재 전에 그해 행을 지운다parallel_max_servers = 32 · db_file_multiblock_read_count = 128DELETE FROM ITEM_SALE_YEAR WHERE SALE_YY = '2013';
INSERT INTO ITEM_SALE_YEAR (SALE_YY, ITEM_ID, QTY, LINE_CNT)
SELECT /*+ FULL(oi) PARALLEL(oi 8) */
'2013', oi.ITEM_ID, SUM(oi.ORD_ITEM_QTY), COUNT(*)
FROM ORD_ITEM oi
WHERE oi.ORD_DT BETWEEN '20130101' AND '20131231'
GROUP BY oi.ITEM_ID;
COMMIT;
[SQL Monitor — INSERT · 일요일 03:00 · DOP 8]
Global Stats
Duration 14s · DB Time 121s · Buffer Gets 55.9K · Read Reqs 470 · Read Bytes 432MB
PX Servers Requested 16 · Allocated 16 (생산자 8 + 소비자 8)
=========================================================================================
| Id | Operation | Name | Execs | Rows | Read | Read |
| | | | | (Actual) | Reqs | Bytes |
=========================================================================================
| 0 | INSERT STATEMENT | | 1 | 1 | | |
| 1 | LOAD TABLE CONVENTIONAL | ITEM_SALE_YEAR | 1 | | | |
| 2 | PX COORDINATOR | | 17 | 92 | | |
| 3 | PX SEND QC (RANDOM) | :TQ10001 | 8 | 92 | | |
| 4 | HASH GROUP BY | | 8 | 92 | | |
| 5 | PX RECEIVE | | 8 | 736 | | |
| 6 | PX SEND HASH | :TQ10000 | 8 | 736 | | |
| 7 | HASH GROUP BY | | 8 | 736 | | |
| 8 | PX BLOCK ITERATOR | | 8 | 1236K | | |
| 9 | TABLE ACCESS FULL | ORD_ITEM | 104 | 1236K | 470 | 432MB |
=========================================================================================
9 - filter(("OI"."ORD_DT">='20130101' AND "OI"."ORD_DT"<='20131231'))