테마
고객센터 「고객 찾기」는 고객을 이름순으로 20명씩 보여 준다. 상담원들이 "영문 이름은 대문자와 소문자가 따로 놀고, '(주)'로 시작하는 법인과 한자 이름이 맨 앞에 몰려 있다"고 하자, 개발팀은 지난주 고객센터 WAS의 연결 풀 초기화 SQL에 ALTER SESSION SET NLS_SORT = KOREAN_M 한 줄을 넣었다. 이름 순서는 상담원들이 원하던 대로 바뀌었다.
그다음 날부터 같은 WAS의 「주문 원장」 첫 화면(고객번호순 50건)이 0.01초에서 0.4초로 늘었다. 상담원 200명이 하루 약 1만 번 연다. 개발팀은 "주문 원장 SQL은 한 글자도 바꾸지 않았다"고 한다.
M_CUS 고객: 2,000행 · 30블록 · CUS_NM VARCHAR2 NOT NULL(대부분 한글 이름이고, 영문 이름 37명, 한자 이름 12명, '(주)'로 시작하는 법인 41곳) · 인덱스 IX_M_CUS_NM (CUS_NM)T_ORD_BIG: 1,000,000행 · 5,826블록 · CUS_ID VARCHAR2(40) NOT NULL(모두 'CUS_' + 숫자 여섯 자리) · 인덱스 IX_ORD_BIG_CUS_DT (CUS_ID, ORD_DT): BLEVEL 2 · 리프 약 3,000블록 · 한 고객의 주문은 테이블 곳곳에 흩어져 있다NLS_COMP는 BINARY 그대로다. 통계는 최신이다.-- 고객센터 WAS 연결 풀 초기화 SQL (지난주 추가)
ALTER SESSION SET NLS_SORT = KOREAN_M;
-- Q1 「고객 찾기」 첫 화면 : 이름순 20명
SELECT CUS_ID, CUS_NM, CUS_GD
FROM M_CUS
ORDER BY CUS_NM
FETCH FIRST 20 ROWS ONLY;
-- Q2 「주문 원장」 첫 화면 : 고객번호순 50건
SELECT CUS_ID, ORD_DT, ORD_SEQ, ORD_AMT
FROM T_ORD_BIG
ORDER BY CUS_ID, ORD_DT
FETCH FIRST 50 ROWS ONLY;
[Q2 · 지난주까지 (세션 NLS_SORT = BINARY)]
------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Used-Mem |
------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 50 |00:00:00.01 | 53 | |
|* 1 | COUNT STOPKEY | | 1 | | 50 |00:00:00.01 | 53 | |
| 2 | VIEW | | 1 | 50 | 50 |00:00:00.01 | 53 | |
| 3 | TABLE ACCESS BY INDEX ROWID | T_ORD_BIG | 1 | 1000K| 50 |00:00:00.01 | 53 | |
| 4 | INDEX FULL SCAN | IX_ORD_BIG_CUS_DT | 1 | 50 | 50 |00:00:00.01 | 3 | |
------------------------------------------------------------------------------------------------------------------------
[Q2 · 지금 (세션 NLS_SORT = KOREAN_M)]
------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Used-Mem |
------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 50 |00:00:00.41 | 5826 | |
|* 1 | COUNT STOPKEY | | 1 | | 50 |00:00:00.41 | 5826 | |
| 2 | VIEW | | 1 | 1000K| 50 |00:00:00.41 | 5826 | |
|* 3 | SORT ORDER BY STOPKEY | | 1 | 1000K| 50 |00:00:00.41 | 5826 | 15360 (0)|
| 4 | TABLE ACCESS FULL | T_ORD_BIG | 1 | 1000K| 1000K|00:00:00.06 | 5826 | |
------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(ROWNUM<=50)
3 - filter(ROWNUM<=50)
Column Projection Information (identified by operation id):
-----------------------------------------------------------
3 - (#keys=2) NLSSORT("CUS_ID",'nls_sort=''KOREAN_M'''), "ORD_DT", "CUS_ID", "ORD_SEQ", "ORD_AMT"
[Q1 · 지금] SORT ORDER BY STOPKEY · TABLE ACCESS FULL M_CUS · Buffers 30 (지난주는 INDEX FULL SCAN IX_M_CUS_NM · Buffers 17)
SORT ORDER BY STOPKEY로 바뀐 까닭을 3번 줄의 정렬 키로 설명하시오.