테마
한빛유통은 결제가 끝난 주문(COMPLETE)을 5분마다 모아 택배사에 배송을 요청한다. 연계 배치는 보낼 주문에 요청 시각을 찍으면서 그 주문번호를 돌려받아 택배사 연계 테이블에 넣는다. 한 번에 300건 안팎인데 한 번 도는 데 0.3초, 하루 288번 돈다.
지난주 DBA가 DLV_REQ_DT에 인덱스를 만들었지만 계획은 그대로다. 조민우는 (DLV_REQ_DT, 0)으로 다시 만들자고 하고, 오과장은 배송 대기 플래그 컬럼을 새로 두자고 한다. 박팀장은 대안을 비교하고 DML 쪽 대가까지 적어 오라고 했다.
T_ORD_BIG: 1,000,000행 · 6,816블록(배송 요청 컬럼을 더한 뒤) · ORD_SEQ 유일 · ORD_ST COMPLETE 90% · PENDING 8% · CANCEL 2%DLV_REQ_DT DATE: 택배사에 배송을 요청한 시각 · 요청 전이면 NULL · 요청 대상은 COMPLETE뿐이라 PENDING 8만 건과 CANCEL 2만 건은 계속 NULL로 남는다 · 5분마다 새로 COMPLETE가 된 주문 약 300건이 NULL로 들어온다
(문제 설정: 교재의 T_ORD_BIG에는 이 컬럼이 없다. 배송 연계 개편 때 더한 컬럼이라고 본다)IX_ORD_BIG_SEQ (ORD_SEQ) 유니크 · IX_ORD_BIG_DLV (DLV_REQ_DT): 지난주 생성 · 리프 2,650 · 통계 최신(NUM_NULLS 100,300)DECLARE
TYPE t_seq_tab IS TABLE OF T_ORD_BIG.ORD_SEQ%TYPE;
v_seq t_seq_tab;
BEGIN
UPDATE T_ORD_BIG
SET DLV_REQ_DT = SYSDATE
WHERE ORD_ST = 'COMPLETE'
AND DLV_REQ_DT IS NULL
RETURNING ORD_SEQ BULK COLLECT INTO v_seq;
PKG_DLV_IF.SEND(v_seq); -- 택배사 연계 테이블에 넣는다
COMMIT;
END;
[UPDATE 한 번 · 300건]
---------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
---------------------------------------------------------------------------------------
| 0 | UPDATE STATEMENT | | 1 | | 0 |00:00:00.31 | 7428 |
| 1 | UPDATE | T_ORD_BIG | 1 | | 0 |00:00:00.31 | 7428 |
|* 2 | TABLE ACCESS FULL| T_ORD_BIG | 1 | 9027 | 300 |00:00:00.29 | 6816 |
---------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter(("DLV_REQ_DT" IS NULL AND "ORD_ST"='COMPLETE'))
IX_ORD_BIG_DLV가 쓰이지 않는 이유를 설명하고, 조민우의 (DLV_REQ_DT, 0)도 이 배치를 빠르게 하지 못하는 이유를 숫자로 설명하시오.(DLV_REQ_DT, ORD_ST) 결합 인덱스 ② 보낼 주문만 담는 함수 기반 인덱스(또는 가상 컬럼) ③ 배송 대기 플래그 컬럼을 새로 두는 모델 변경을 비교하시오. 인덱스 크기와 UPDATE마다 드는 인덱스 유지 비용을 함께 따지시오.