테마
본사 레거시 유통의 매장 POS(6개 매장)는 판매를 저장할 때 판매번호를 날짜 여덟 자리와 하이픈, 그날의 네 자리 일련번호로 매긴다('20231231-0612'). 일련번호는 날마다 0001부터 다시 시작한다.
매장에서는 결제 저장이 건마다 0.3초씩 멈칫한다고 하고, 손님이 몰리는 토요일 오후에는 하루 서너 번 ORA-00001: unique constraint (PUP.CF10_PK) violated로 저장이 실패해 결제를 다시 한다.
CF10 판매: 500,000행 · 4,583블록 · SLE_NO VARCHAR2(15) · SLE_DT VARCHAR2(8) · 하루 약 700건 · 토요일 오후 피크는 분당 6 ~ 8건CF10_PK (SLE_NO) 하나뿐이다(BLEVEL 2 · 리프 약 1,650블록) · SLE_DT에는 인덱스가 없다 · 통계 최신CF11 판매상품: 1,096,708행 · CF11_PK (SLE_NO, ITM_NO) · 판매당 약 2.2행CF10 INSERT → CF11 INSERT(상품마다) → COMMIT · 카드 승인은 저장 전에 끝난다-- PKG_POS.SAVE_SALE — 판매번호 받기
SELECT :dt || '-' || LPAD(NVL(MAX(TO_NUMBER(SUBSTR(SLE_NO, 10, 4))), 0) + 1, 4, '0')
INTO v_sle_no
FROM CF10
WHERE SLE_DT = :dt;
INSERT INTO CF10 (SLE_NO, SLE_DT, SLE_HMS, SLE_DOW, SHP_NO)
VALUES (v_sle_no, :dt, :hms, :dow, :shp_no);
-- 상품마다 CF11 INSERT → COMMIT
[번호 받기 — ALLSTATS LAST · 2023-12-16(토) 15시]
-------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.29 | 4583 |
| 1 | SORT AGGREGATE | | 1 | 1 | 1 |00:00:00.29 | 4583 |
|* 2 | TABLE ACCESS FULL| CF10 | 1 | 685 | 512 |00:00:00.29 | 4583 |
-------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("SLE_DT"=:DT)
[시간표 — 15:12:40 · 매장 둘]
시각 매장 1003 (SID 34) 매장 1005 (SID 71)
15:12:40.00 번호 받기 시작 (FULL 4,583블록)
15:12:40.12 번호 받기 시작
15:12:40.29 → 20231216-0513 · CF10 INSERT · CF11 INSERT
15:12:40.41 → 20231216-0513 (34 의 행은 COMMIT 전) · CF10 INSERT
→ 기다림 (TX REQUEST 4)
15:12:40.45 COMMIT → ORA-00001 · POS "저장 실패, 다시 결제하세요"