테마
18화 · 튜너가 되는 날
🗓️ 7월 8일 (월) · 17화에서 일주일 뒤 · 무대
ora-hanorder(한빛유통) · 저녁에는ora-newshop(신규 이커머스) · 4막의 마지막 화 · 이 교재의 마지막 화오늘 배울 것: 결정과 그 결정이 기대던 규모를 따로 적으면, 다음 사람에게는 결정만 도착한다. 3월 4일에 만든 원장에 2열을 붙이고, 계획을 베이스라인으로 지키고, 튜닝 어드바이저가 내놓은 99.42%를 직접 재 보고 기각한다. 근거 수치가 없는 후배의 리포트는 숫자로 다시 쓰고, 18주 동안 쓴 리포트에서 두 번 이상 나온 원인만 골라 사내 튜닝 표준을 만든다. 그리고 처음 보는 고객사를 혼자 진단한다. 리비전은 하나(Q2 rev02)다. 산출물은 T6 사내 튜닝 표준 v1.0, SQL 코딩 가이드 v1.0, W01 원장 2열, 리비전 대장, 졸업 과제다.
파일 세 개
| 파일 | 무엇을 하나 | 시간 | |
|---|---|---|---|
| 읽는다 | 1_사건.md | 3월에 만든 원장을 다시 연다. Q4 rev00이 1,007이 된 것을 '빨라졌다'고 읽을 뻔하고, 힌트를 박자고 했다가 1층 엘리베이터 홀의 합격증을 본다. 99.42% 프로파일을 받았다가 그 두 줄을 읽고 기각한다. 정하은 씨의 "3배 빨라졌습니다"에 "누가 잰 거예요?"라고 묻고, 배치와 화면을 함께 돌려 리소스 플랜이 약속을 지키지 않는 것을 확인한다. 옛 판과 지금 판을 한 리포트에 놓고 비교한 뒤 마지막 조항을 두 번 고쳐 쓴다. 저녁에는 봉투 하나를 받는다 | 50분 |
| 한다 | 3_실습과_기록.md | W01 2열 · SPM · STA · 팩 확인란 · Q2 rev02 · 리소스 매니저 · awrddrpt · 넘겨받은 것 · T6 · 코딩 가이드 v1.0 · 리포트 여섯 · 졸업 과제(ora-newshop) | 3시간 + 졸업 과제 반나절 |
| 찾는다 | 2_파고들기.md | 원장 재측정의 조건 · SPM의 말 셋과 두 장면 · Free의 자동 기능 · STA와 프로파일의 정체 · 팩을 끄면 · Q2 rev02의 CPU · 리소스 매니저 네 판 · awrddrpt · 승격 규칙 · 넘겨받은 것 전부 · 남긴 흔적 · 원천 좌표 | 필요할 때 |
1을 읽고 3을 따라 한다. 2는 막힐 때 펼친다. 시간이 없는 주에는 1_사건을 중단 지점 2까지 읽고, 3_실습은 STEP 0, 2, 6, 10, 12만 한다(원장 2열, 후배 리포트, 표준, 졸업 과제).
지난 화에서 들고 오는 것
| 01화 | W01 베이스라인 원장: 6조각 1,045,169블록 · 전제 "T_ORD_BIG 인덱스 0개" · 마지막 줄 "18화 재측정 예정" · T0 측정규약(18화까지 불변) |
| 06화 | 회의록 "3초 → 0.4초"와 첨부 끝 줄 "주문 20,000건" · 힌트 유효기간 대장("졸업 판정 (18화): 대장 전체를 재측정") |
| 08화 | Q2 보류안: 먼저 묶기(Buffers가 같아서 리비전으로 올리지 않았다) · 정합성 회귀 체크리스트("18화 졸업 판정: 불일치가 하나라도 남아 있으면 미완성") |
| 10화 | 그 일요일 밤: 빈 테이블 통계 한 번에 Q2 1,026,852 · 통계 수집 정책서 |
| 11화 · 15b화 | SQL 코딩 가이드 v0.1: 조문 1 ~ 11 · 〔근거 n회〕 |
| 15b화 | 결과 캐시 재적용 · RESULT_CACHE 전수 점검 · 조문 11 승격 · 체크리스트 '시각 · 세션' 줄 → 18화 |
| 16화 | Q2 = DB CPU 47.5%(보류안 조건 충족) · T2-002 IX_ORD_BIG_DT 폐기 · T5 · T7 · T8의 규칙 → 18화 |
| 17화 | 진단 도구 4열 대응표 · 질문 셋(평균인가 · 횟수인가 · 언제인가) · ADDM Top SQL → SQL Tuning Advisor · SPM · 교차검증판 · IN_SEQUENCE_LOAD(열어 둠) |
월요일 아침에는 메시지가 세 개 와 있다.
"오늘부터 정하은 씨가 합류합니다. 오후에 하은 씨 리포트 리뷰 부탁해요. 반기 보고에 '튜닝 표준' 한 장 넣기로 했습니다." (박팀장, 08:41) "월마감 집계를 오늘 오전에 다시 돌려야 하는데, 낮에 돌리면 화면 느려지죠? 리소스 매니저로 막을 수 있다고 들었는데요." (오과장, 08:55) "오늘은 내가 옆에 안 앉아. 물으면 답은 할게. 대신 내가 먼저 묻지는 않을 거야." (윤세라, 09:10)
오늘의 전개 — 내가 틀린 자리를 잰다
| 내가 믿은 것 | 측정 (ora-hanorder · 17화 종료 상태 · 단일 세션 / 부하 판은 3세션) | |
|---|---|---|
| 09:30 | "강도현 씨 코드가 빨라졌네요. Q4 rev00이 5,826에서 1,007로" | SQL은 그대로 · 09화 인덱스(IX_ORD_BIG_DT_SEQ)를 rev00도 쓴다 · 계획 513693594 → 3040227993 · 3월의 원장은 "인덱스 0개 ← 전제"를 적어 두었기 때문에 반박되지 않았다 |
| 09:50 | (원장 2열) | 1,045,169 → rev00 그대로 1,037,887(−0.7%) → 최신판 6,812(−99.3%) · P1 2,480ms와 1,000 안팎은 같은 코드다. 초만으로는 가를 수 없어서 일의 양을 같이 본다 |
| 10:40 | "Q2에 USE_HASH를 박아 두면 통계가 무슨 일을 해도" | 06화에 뗀 것과 같은 일 · SQL Plan Management: 인덱스가 생겨도 FULL(합격증) → 진화 63.7배 → 91 / 빈 테이블 통계에서도 HASH 5,868 유지 · 끄면 NL 1026K · NL은 진화에서 0.33배로 탈락 · 자동 진화는 Free에서 ORA-38153 |
| 11:40 | "튜닝 어드바이저가 99.42%를 약속한다. 배포 없이 고칠 수 있다" | 프로파일의 정체는 IGNORE_OPTIM_EMBEDDED_HINTS: 박힌 힌트를 코드 밖에서 무시하게 한다 · 소스에는 USE_NL이 남는다 · 띄어쓰기를 바꿔도 붙는다 · 50배로 틀린 Q3 rev00에는 권고 없음 |
| 12:30 | (튜닝 팩을 끄면) | 과제 ORA-13717 · 받아 둔 프로파일은 에러 없이 무시 → 1026K · 베이스라인은 쓰인다 → 프로파일 기각(T1 13호) · 팩 설정 되돌림 |
| 13:20 | 정하은 "약 3배 빨라졌습니다 (개발 DB 테스트 완료)" | "누가 · 몇 번 · 무엇으로 · 몇 건에서?" → Buffers 5,868 = 5,868 · CPU 10회 115 → 33cs(6묶음) · MINUS 0 / 0 · 경계 둘 같음 · 16화 47.5% → Q2 rev02(T1 12호) |
| 14:30 | "온라인 90, 배치 10이면 화면은 거의 원래대로" | 단독 41,741 /분 → 배치와 겹침 20,497 → 90/10 플랜 23,754(+16 ~ 19%) · 상한 10%에서 배치 CPU 265초 vs 온라인 342초: 약속대로 나누지 않았다 · 원인 미확인 → 재실행은 19시 이후(T3 3호) |
| 15:30 | (awrddrpt: 옛 판 셋 vs 지금 판) | DB time 24.0 vs 24.1분(같은 3세션) · 일은 6.2배 · Logical read −94.5% · Redo −97.8% · 시간 모델 1위 sequence load 48.3%는 결론에 쓰지 않는다(ASH로 세면 시퀀스를 안 부르는 조각의 표본) (T5-003) |
| 16:30 | "강도현은 숫자를 남기지 않았다" → "규모를 남기지 않았다" | 회의록 본문에 3초 → 0.4초 · 첨부 끝 줄에 주문 20,000건 · 소스에는 "건드리지 말 것" 한 줄: 셋 다 있었지만 한곳에 있지 않았다 → 마지막 조항 |
| 17:30 | (봉투: ora-newshop · 설명서 두 개) | 첫 쿼리부터 설명서와 다르다. 그다음은 독자의 몫(졸업 과제) |
왜 이렇게 짰을까? 18주 동안 매 화는 강도현의 결정 하나를 붙잡고 "그때는 왜 옳았는가"를 밝혀 왔다. 이번 화는 그 질문을 나에게 돌린다. 3월의 원장은 전제를 적어 두었기 때문에 7월에 반박되지 않았다. 오늘 쓴 리비전과 베이스라인, 표준도 그날의 규모 위에 서 있다. 그래서 표준의 마지막 조항은 새 규칙이 아니라 3월 4일에 그린 화살표 하나다.
오늘 배우는 한 문장
결정과 그 결정이 기대던 규모를 따로 적으면, 다음 사람에게는 결정만 도착한다. 합격증의 '합격'은 정격하중과 한 장에 적혀 있을 때만 뜻이 있다. 3월의 원장이 7월에 지워지지 않은 것은 숫자 바로 위에 전제가 적혀 있었기 때문이다.
| 계획을 지키는 장치 | 어디에 있나 | 새 계획이 더 나은지 검사하나 | 팩을 끄면 |
|---|---|---|---|
힌트(USE_NL) | 코드 안 | 아니다. 그대로 실행된다 | 상관없다 |
| SQL 프로파일 | 코드 밖(딕셔너리) | 아니다. 받는 순간 붙는다 | 에러 없이 사라진다 |
| SQL plan baseline | 코드 밖(딕셔너리) | 한다. 진화(시험 운행)로 검사한다 | 상관없다(팩 기능이 아니다) |
🔑 오늘의 비유 — 1층 엘리베이터 홀의 승강기 검사합격증명서
| 1층 엘리베이터 홀 | 오라클 |
|---|---|
| 합격증이 붙은 승강기만 운행한다 | 베이스라인에 ACCEPTED로 들어 있는 계획만 실행된다 |
| 새 승강기를 들여와도 검사 전에는 운행하지 않는다. 원래 승강기가 계속 다닌다 | 옵티마이저가 새 계획을 만들어도 대기 줄(ACCEPTED NO)에 세워 두고, 원래 계획을 그대로 쓴다 |
| 검사: 실제로 태워 보고 기준을 넘으면 합격 | 진화: 두 계획을 실제로 돌려 보고 N times better면 받아들인다 |
| 운행 정지 딱지 · 새 승강기 반입 금지 | ENABLED = NO · FIXED = YES |
| 정격하중 1,000kg · 정원 15명 · 유효기간: '합격'의 뜻은 이 작은 글씨에 있다. 한 장에 적혀 타는 문 옆에 붙어 있다 | 그 당시의 데이터 규모와 근거 수치를 함께 적는다: T6 마지막 조항 |
| 화물 운행 안내: 평일 19:00 이후 · 3호기만(17화의 이삿짐 뒤에 붙었다) | 리소스 플랜이 비율을 지키지 않을 때는 시간으로 나눈다(T3 3호) |
예전 비유도 다시 나온다. 06화 회의록(본문과 첨부, 소스가 따로 있던 것), 16화 검침 대장과 17화 녹화기(같은 건물, 이번에는 1층), 그리고 01화의 "30초라는 건 누가 잰 거야?"(오늘은 내가 묻는다)다.
☠️ 오늘의 함정 — 도구 · 문서 · 후배가 내놓은 '그럴듯한 답'
'rev00 이 오늘 1,007 — 강도현 코드가 빨라졌다' → SQL 은 그대로. 바닥(인덱스)이 바뀌었다
'힌트로 박아 두면 통계가 무슨 일을 해도' → 06화에 뗀 것과 같은 일. 검사하는 장치는 베이스라인
'튜닝 어드바이저 99.42 % — 배포 없이' → 박힌 힌트를 무시하라는 두 줄. 팩을 끄면 에러 없이 1026K
'50배로 틀린 Q3 rev00 — 어드바이저가 아무 말 없다' → 도구는 빠른지를 본다. 맞는지는 안 본다
'약 3배 빨라졌습니다 (개발 DB 테스트 완료)' → 결론은 맞았다. 측정이 없었다 — 증언
'Buffers 가 같으니 리비전이 아니다' → T0 로는 맞다. CPU 115 → 33 + 시스템 몫 47.5 % 가 근거
'90/10 플랜이면 화면은 원래대로' → 이 Free 에서는 16 ~ 19 % 만. 상한 10 % 그룹이 CPU 44 %
'awrddrpt — DB time 이 같다' → 같은 3세션이 쉬지 않았을 뿐. 일은 6.2배
'%Diff 1위 sequence load 48.3 %' → 시퀀스를 안 부르는 조각의 표본에도 켜진 깃발
'설명서: FK 제약 0' → (졸업 과제)실습 준비
bash
docker start ora-hanorder
MSYS_NO_PATHCONV=1 docker exec -i ora-hanorder sqlplus -s / as sysdba < 실습/01_튜닝권한_SYSDBA.sql17화를 마친 상태에서 시작한다. 실습/00_준비와_점검.sql이 그 상태를 확인한다(인덱스 셋 · ORD_ST FREQUENCY · PKG_LOAD_DRIVER VALID · 도는 드라이버 세션 0 · SQ_STLM_LD CACHE 20 · 베이스라인 · 프로파일 · C18 객체 0). 졸업 과제를 하려면 ora-newshop의 ECOMMERCE가 L4 카드대로 만들어져 있어야 한다(30개 테이블, 445,422행).
PowerShell에서는 먼저
$OutputEncoding = New-Object System.Text.UTF8Encoding $false한 줄을 실행한다. SYS 스크립트(_SYSDBA)는 Git Bash에서MSYS_NO_PATHCONV=1 docker exec -i ora-hanorder sqlplus -s / as sysdba < …로 돌린다.
| 스크립트 | 무엇 | 계정 | 소요 |
|---|---|---|---|
실습/00_준비와_점검.sql | 전제 · 원본 지문 · 오늘 쓸 것 0 · 설정 · 권한 | sqlp | 수 초 |
실습/01_튜닝권한_SYSDBA.sql | sqlp에 ADVISOR · ADMINISTER SQL MANAGEMENT OBJECT | SYS | 1초 |
★ 실습/02_W01_재측정.sql | 6조각: rev00 그대로 · 최신판 · P1 · N1(복사본) | sqlp | 10초 |
★ 실습/03_SPM_계획을_지킨다.sql | 베이스라인 두 장면 · 진화 · FIXED · ENABLED · 자동 캡처 | sqlp | 10초 |
실습/04_SPM_자동기능_SYSDBA.sql | Free의 자동 진화 · 자동 튜닝 | SYS | 1초 |
★ 실습/05_튜닝_어드바이저.sql | STA 여섯 · 프로파일 받기 · 정체 · 서명 · 지우기 | sqlp | 10초 |
★ 실습/06_팩_확인란_SYSDBA.sql | 팩 네 판(메모리만) → 되돌린다 | SYS | 5초 |
실습/07a_리소스플랜_만들기_SYSDBA.sql · 07_격리_세_판.sh · 07_배치_일꾼.sql · 07c_격리_결과.sql | 리소스 매니저: 5분씩 네 판 | SYS + Git Bash | 21분 |
실습/08_옛판_지금판.sh · 08_구간_스냅샷_SYSDBA.sql · 08b_awrddrpt_SYSDBA.sql · 08c_두_구간_요약_SYSDBA.sql | 옛 판 10분 · 지금 판 10분 · 비교 리포트 | SYS + Git Bash | 21분 |
★ 실습/09_Q2_보류안_T1.sql | Q2 rev01 vs rev02: CPU · 정합성 · 경계 | sqlp | 6초 |
실습/10_IX_ORD_BIG_DT_관찰.sql | T2-002: 사용 · AWR · INVISIBLE 한 걸음 → 되돌림 | sqlp | 2초 |
실습/11_결과캐시_점검.sql | 15b화가 넘긴 셋 | sqlp | 1초 |
실습/99_정리_SYSDBA.sql | 17화 종료 상태로 · 마지막 표로 확인 | SYS | 수 초 |
실습/졸업과제/: E00 · E1 ~ E4_rev00 · E01 · 🔒 E90 · 🔒 E91 · E99 | ora-newshop 혼자 진단 · 봉인 복구 | SYS + ecommerce | 반나절 |
두 번 돌려도 판정은 같다. 이 화의 스크립트는 전부 두 번씩 돌렸다. 계획 해시와 Buffers, 판정은 같았고 초와 CPU, 진화 배수는 조금씩 흔들렸다(범위는
2_파고들기 §11에 있다). 원본 테이블에는 한 줄도 쓰지 않는다. 인스턴스 설정은 세 가지를 바꿨다가 되돌린다. 팩 설정(06, 메모리만), PDB 리소스 플랜(07, 메모리만, 빈 값으로 끄지 않는다),IX_ORD_BIG_DT가시성(10)이다. ℹ️ Docker로 띄운 Oracle Database Free 한 대로 끝까지 진행한다. Free에는 자동 SPM 진화가 없고(ORA-38153), 이 PDB의 리소스 플랜은 비율과 상한을 약속대로 지키지 않았다(원인 미확인). 운영 EE의 리소스 관리와 병렬, RAC는 별권에서 다룬다.
이 화의 산출물
| 무엇 | 어디 |
|---|---|
| T6 사내 튜닝 표준 v1.0: 조문 16(근거 2회 이상) · 대기 줄 9 · 코드 리뷰 체크리스트 26문 · 팩 라이선스 확인란 · 문서 운용 · 마지막 조항 | 40_보고서와_표준/표준/T6_사내_튜닝표준_v1.0.md |
| SQL 코딩 가이드 v1.0: 조문 8 · 11(넓혀 승격) · 12 · 13 · 14(신설) · 대기 조문 1 ~ 7 · 9 · 10 · 체크리스트 D | 40_보고서와_표준/템플릿/SQL_코딩가이드.md |
| W01 베이스라인 원장의 18화 2열(01화 기록은 그대로) | 40_보고서와_표준/제출물/W01_베이스라인_원장.md |
| 리비전 대장: 화 01 ~ 18 × 조각 Q1 · Q2 · Q3 · Q4 · P1 · N1(+ B1 · ADJ · SDT) | 40_보고서와_표준/제출물/리비전_대장.md |
| 힌트 유효기간 대장: 졸업 재측정(4 · 5번 행, 3번 행 정정) | 40_보고서와_표준/템플릿/힌트_유효기간_대장.md |
| 정합성 회귀 체크리스트: 경계 목록 '시각 · 세션' 줄 | 40_보고서와_표준/템플릿/정합성_회귀_체크리스트.md |
| T1 12호(Q2 rev02) · T1 13호(프로파일 기각) · T3 3호 · T5-003 · T7 3호 · T2-002 갱신 | 3_실습 STEP 11 |
리비전/ | Q2_rev02.sql: 먼저 묶기(Buffers 5,868 → 5,868 · CPU 115 → 33cs) |
| 졸업 과제: 산출물 여덟 · 채점표 · 🔒 모범 답안 | 3_실습 STEP 12 |
| 이커머스 설명서 정정(지우지 않고 옆에 · 🔒 상자) | ERD 조감도 · 구축가이드 |
이 화가 넘기는 것
이 교재는 여기서 끝난다. 다음 화는 없다.
| 무엇 | 어디로 |
|---|---|
졸업 과제: ora-newshop의 리포트(대기 조문 7 · 9의 두 번째 근거가 될 수 있다 → 표준 v1.1) | 독자 |
| 운영 EE의 리소스 매니저 · 자동 SPM 진화 · 병렬 · RAC · 진짜 팩 없는 서버 | 별권 |
← 17화 「평균은 거짓말을 한다」 · 교재 전체 안내 · 다음 화 없음(이 교재의 마지막 화이며, Free 밖의 것은 별권에서 다룬다)