테마
콜센터의 「고객 360」은 상담원이 고객명 앞부분을 넣으면 고객 정보와 주문, 정산, 평가 요약을 한 줄씩 보여 준다. 동명이인이 있어 보통 두 명쯤 나온다. 상담원 40명이 통화마다 열어 하루 6,000번 돌고, 한 번은 0.04초지만 하루 논리 읽기는 약 490만 블록으로 콜센터 전체의 절반이다. 박팀장은 "인덱스는 꼭 필요한 것만 만든다. 정산 테이블은 매일 밤 비우고 다시 싣는 테이블이니 그 비용까지 적어 와라"라고 했다.
M_CUS 고객: 2,000행 · 30블록 · PK_M_CUS (CUS_ID) · CUS_NM에는 인덱스가 없다T_ORD 주문: 100,000행 · 896블록 · IX_ORD_CUS (CUS_ID) (다른 콜센터 화면도 쓴다) · 고객당 약 50건 · 한 고객의 주문은 흩어져 있다T_ORD_STLM 정산: 100,000행 · 640블록 · 인덱스 없음 · 고객당 약 50건 · 매일 밤 TRUNCATE 뒤 INSERT /*+ APPEND */로 10만 건을 다시 싣는다(지금 약 0.1초)T_ITM_EVL 상품평가: 5,000행 · 48블록 · PK_T_ITM_EVL (ITM_ID, EVL_LST_NO)만 있다 · 고객당 2 ~ 3건 · 리뷰가 올라올 때마다 한 건씩 들어온다SELECT c.CUS_ID, c.CUS_NM, c.CUS_GD,
o.ORD_CNT, o.ORD_AMT, o.LAST_ORD_DT,
s.STLM_AMT,
e.EVL_CNT, e.AVG_PT
FROM M_CUS c,
(SELECT CUS_ID, COUNT(*) AS ORD_CNT, SUM(ORD_AMT) AS ORD_AMT, MAX(ORD_DT) AS LAST_ORD_DT
FROM T_ORD GROUP BY CUS_ID) o,
(SELECT CUS_ID, SUM(STLM_AMT) AS STLM_AMT
FROM T_ORD_STLM GROUP BY CUS_ID) s,
(SELECT CUS_ID, COUNT(*) AS EVL_CNT, ROUND(AVG(EVL_PT), 2) AS AVG_PT
FROM T_ITM_EVL GROUP BY CUS_ID) e
WHERE c.CUS_NM LIKE :nm || '%'
AND o.CUS_ID(+) = c.CUS_ID
AND s.CUS_ID(+) = c.CUS_ID
AND e.CUS_ID(+) = c.CUS_ID
------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Used-Mem |
------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 2 |00:00:00.04 | 822 | |
|* 1 | HASH JOIN OUTER | | 1 | 2 | 2 |00:00:00.04 | 822 | 1123K (0)|
|* 2 | HASH JOIN OUTER | | 1 | 2 | 2 |00:00:00.03 | 774 | 1036K (0)|
| 3 | NESTED LOOPS OUTER | | 1 | 2 | 2 |00:00:00.01 | 134 | |
|* 4 | TABLE ACCESS FULL | M_CUS | 1 | 2 | 2 |00:00:00.01 | 30 | |
| 5 | VIEW PUSHED PREDICATE | | 2 | 1 | 2 |00:00:00.01 | 104 | |
| 6 | SORT GROUP BY | | 2 | 1 | 2 |00:00:00.01 | 104 | |
| 7 | TABLE ACCESS BY INDEX ROWID BATCHED| T_ORD | 2 | 50 | 100 |00:00:00.01 | 104 | |
|* 8 | INDEX RANGE SCAN | IX_ORD_CUS | 2 | 50 | 100 |00:00:00.01 | 4 | |
| 9 | VIEW | | 1 | 2000 | 2000 |00:00:00.03 | 640 | |
| 10 | HASH GROUP BY | | 1 | 2000 | 2000 |00:00:00.03 | 640 | 1405K (0)|
| 11 | TABLE ACCESS FULL | T_ORD_STLM | 1 | 100K | 100K |00:00:00.01 | 640 | |
| 12 | VIEW | | 1 | 1990 | 1990 |00:00:00.01 | 48 | |
| 13 | HASH GROUP BY | | 1 | 1990 | 1990 |00:00:00.01 | 48 | 1289K (0)|
| 14 | TABLE ACCESS FULL | T_ITM_EVL | 1 | 5000 | 5000 |00:00:00.01 | 48 | |
------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("E"."CUS_ID"(+)="C"."CUS_ID")
2 - access("S"."CUS_ID"(+)="C"."CUS_ID")
4 - filter("C"."CUS_NM" LIKE :NM||'%')
8 - access("CUS_ID"="C"."CUS_ID")