Skip to content

T6 — 사내 튜닝 표준 v1.0 ​

18화에 제정했다(7월 8일 월요일 · ㈜한빛유통 튜닝팀). 조문 열여섯 개와 코드 리뷰 체크리스트, 마지막 조항 하나로 이루어진다. 승격 규칙: 지금까지의 리포트에서 두 번 이상 나온 원인만 조문이 된다. 표준을 정하는 것은 저자의 취향이 아니라 리포트다. 한 번만 나온 원인은 버리지 않는다. 대기 줄(§2)에 세워 두고, 같은 원인이 한 번 더 나오면 그날 조문으로 올린다. 이 표준은 T0 측정규약을 고치지 않는다. T0는 "무엇으로 재는가"(Buffers N → M)를 정했고, T6은 "그 숫자 옆에 무엇을 함께 적는가"를 정한다.


0. 이 표준은 어떻게 만들어졌나 ​

원천 — 18주 동안 쓴 리포트 ​

양식번호 (화)
T1 단건 SQL1호 (02) · 2호 (03) · 3호 (05) · 4호 (06) · 5호 (07) · 6호 (08) · 7호 (09) · 8호 (10) · 9호 (11) · 10호 = T4 2호 (13) · 11호 (15b) · 12호 · 13호 (18)
T2 승인서T2-001 (04) · T2-002 (04 → 14 → 16 → 18)
T3 배치 SLA1호 (14) · 2호 (15) · 3호 (18)
T4 포스트모템1호 (12) · 2호 (13)
T5 시스템T5-001 (16) · T5-002 (17) · T5-003 (18)
T7 · T8T7 1호 (16) · 2호 (17) · 3호 (18) · T8 1호 (16)
그 밖03화 정합성 이상 보고 · 힌트 유효기간 대장 1호 (06) · 화면 요구 재협상서 1호 (09) · 통계 수집 정책서 1 · 2호 (10)

승격 절차 ​

  1. 리포트마다 원인 칸에 적힌 말을 그대로 뽑는다(원인 칸이 비어 있으면 그 화 본문의 말을 쓴다).
  2. 같은 원인끼리 묶는다. 겉모양(조각 · 화면 · 장비)이 아니라 무엇 때문에 틀렸나로 묶는다.
  3. 서로 다른 리포트 둘 이상에서 나왔으면 조문, 하나뿐이면 §2 대기 줄에 둔다.
  4. 조문마다 각주를 세 개 단다: [근거 리포트], [성능고도화 권-장-절], [공식문서 매뉴얼-장]. 원천 좌표는 그 리포트를 쓴 화의 2_파고들기 「원천 좌표」 절에 이미 적힌 것만 옮긴다(18화의 몫인 SPM · SQL Tuning Advisor는 원천지도/오라클공식문서_지도.md의 18화 줄에서 옮긴다). 거기에도 없으면 「좌표 미확인」이라고 쓴다(지어내지 않는다). 각주에서 좌표 옆 괄호 안의 숫자는 그 좌표를 적은 화다.

승격 판정표 (요약) ​

원인리포트횟수판정
결정 · 보고에 그때의 규모와 근거 수치가 없다 · 전제를 적지 않아 결정이 유효기간을 넘겼다T2-001 · T1 4호 · 대장 1호 · T1 6호 · T1 7호 · T1 8호 · T4 1호 · T1 11호 · T1 12호9마지막 조항
한 칸 · 한 비율 · 한 평균을 결론으로 썼다T1 5호 · T5-001 · T8 1호 · T5-0024제1조
Buffers로는 안 보이는 것(TEMP · CPU · 정답 · 시계)이 회귀했다T1 4호 · T1 5호 · T1 6호 · T1 7호 · T1 11호 · T1 12호6제2조
측정 조건 · 부하 모델이 운영과 달랐다T1 5호 · T1 9호 · T3 1호 · T7 1호 · T5-001 · T3 2호6제3조
컬럼을 가공해 인덱스 · 통계를 잃었다T1 1호 · T1 2호2제4조
'이 데이터에서 같다'를 '맞다'로 읽었다T1 1호 · T1 2호(+정합성 이상 보고) · T1 6호 · T3 2호 · T1 11호5제5조
행마다 건너가는 일(왕복 · 래치 · 재귀 호출 · 함수)의 횟수T1 4호 · T1 5호 · T3 1호 · T3 2호4제6조
통계 상태가 계획을 정했다T1 8호 · T3 1호 · T1 9호3제7조
처방을 패턴이 아니라 모양으로 옮겼다 (커밋 · 채번 · 배치)T4 1호 · T4 2호 · T3 1호 · T3 2호4제8조
서버 스위치 · 자원 증설로 덮자는 제안T1 7호 · T1 9호 · T5-0013제9조
도구의 권고를 근거 칸 없이 따르려 했다T5-001 · T5-002 · T1 13호3제10조
리스크 칸이 비었거나, 그 일을 할 사람이 안 읽는 곳에 적혔다T4 1호 → T4 2호 · T1 7호 → T1 9호4 (사슬 둘)제11조
바꾸는 것의 영향 범위를 안 봤다 (카디널리티 · 적재 순서 · 보관 정책 · 버그 수정)T1 6호 · T4 1호 · T2-001 · T1 3호4제12조
요구를 다시 묻지 않았다T1 7호(+재협상서 1호) · T4 1호2제13조
에러 없이 사라진 것 (삼킨 예외 · 반쯤 반영)T3 2호 · T4 2호 · T3 1호3제14조
인자로 들어오지 않는 입력 (NLS · 시계 · 세션)T1 2호 · T1 11호2제15조
팩 계약 · 팩 설정에 기대는 도구와 해결책T5-002 · T1 13호2제16조

18화의 리포트(T1 12 · 13호 · T5-003 · T3 3호)도 근거로 센다. 18화도 리포트를 쓴 날이기 때문이다. 다만 18화 리포트 하나만으로 올린 조문은 없다(제2 · 10 · 16조는 앞 화의 리포트가 먼저 있었다).


1. 조문 ​

제1조 한 칸으로 결론을 내지 않는다 ​

리포트의 한 칸, 한 비율, 한 평균은 결론이 아니다. 다른 칸에서도 같은 사실이 확인될 때까지 대조한다.

  • 비율(히트율 · Execute to Parse % …) 옆에는 분자와 분모의 초당 값을 같이 적는다.
  • 시간을 나타내는 숫자에는 세 질문의 답을 붙인다. 평균인가, 횟수인가, 언제인가(진단 도구 4열 대응표에서 그 질문에 답하는 칸을 고른다).
  • 한 시간짜리 평균으로 현업이 말한 '몇 분'을 기각하지 않는다. 평균은 '언제'를 본 뒤에만 쓴다(세칙 · 17화 T5-002).
근거 리포트성능고도화공식문서
T1 5호 (07화 · 히트율 99.89 → 80.17%, 물리 읽기 11,626 = 11,626) · T5-001 (16화 · Buffer Hit 99.99% · CPU 2.01 · Elapsed 1위, 셋 다 다른 칸과 어긋남) · T8 1호 (16화 · 고쳤더니 Execute to Parse 73.05 → 63.28) · T5-002 (17화 · enq: TX 한 칸 5.5% · 5분 칸 100%)I권 03장 05절 Ratio 기반 분석 (p.194 ~ 198 · 16화) · 08절 Statspack / AWR (p.210 · 212 · 214 · 16 · 17화) · 09절 ASH (p.220 ~ 224 · 17화) · I권 「버퍼 캐시 히트율」 (p.441 · 07화)tgdba Gathering Database Statistics (Automatic Workload Repository) (16화) · tgdba Analyzing Sampled Data (17화) · tgdba Tuning the Database Buffer Cache (07화)

제2조 Buffers로 안 보이는 값은 같은 조건으로 함께 적는다 ​

T0의 판정 기준은 Buffers N → M이다. 그런데 Buffers가 같거나 이미 바닥인데도 바뀐 것(TEMP 패스 · CPU · 결과 · 시각)이 있다면, 그 값을 같은 조건으로 재서 옆에 적는다.

  • CPU는 같은 세션, 같은 데이터로 데우기를 한 뒤 10회 합을 세 번 잰다(한 번 잰 초는 증거가 아니다).
  • 그 SQL이 시스템에서 차지하는 몫(T5 · AWR)이 함께 있을 때만 CPU를 채택 근거로 쓴다(18화 T1 12호 · Q2 rev02).
근거 리포트성능고도화공식문서
T1 4호 (06화 · Buffers 5,869 / 5,868 · 0.17 → 7.7초, 책상이 좁아지면) · T1 5호 (07화 · rev01의 CPU 절반이 스칼라 캐시 탐색) · T1 6호 (08화 · 839 → 839 · 금액 50배) · T1 7호 (09화 · 64KB 책상 184 PASSES) · T1 11호 (15b화 · 계획 · Buffers · 해시 셋 다 같은데 정산일이 멈춤) · T1 12호 (18화 · 5,868 → 5,868 · CPU 115 → 33cs)II권 Ch2 03절 해시 조인 (p.249 ~ 264 · 06화) · II권 Ch5 01절 소트 (p.572 ~ 580 · 09화)tgdba Tuning the Program Global Area (09화) · tgdba Tuning the Database Memory (PGA Memory Management) (06화)

제3조 측정 조건과 부하 모델을 적고, 운영과 다른 점을 적는다 ​

연습 DB의 숫자는 그 조건에 따라 달라진다. 캐시 상태, statistics_level, 부하 발생기의 문장, 세션 수, 장비가 모두 조건이다. 다른 점을 적지 않은 측정은 증거가 아니다.

  • 시스템 리포트(T5)는 워크로드 프로파일 ID(T7)가 없으면 무효다.
  • 연습 DB의 초를 운영의 초로 옮기지 않는다(T3의 규칙을 모든 리포트에 적용한다).
근거 리포트성능고도화공식문서
T1 5호 (07화 · 같은 SQL의 히트율이 캐시 상태에 따라 1% ~ 100%) · T1 9호 (11화 · statistics_level = ALL로 재자 ACS가 고쳐졌다. TYPICAL에서는 아니다) · T3 1호 (14화 · 연습 DB 329초) · T7 1호 (16화 · 발생기의 Q2는 운영 문장이 아니었다) · T5-001 (16화) · T3 2호 (15화 · 연습 DB의 1/8은 운영의 1/8이 아니다)I권 03장 「오라클 성능 관리」 (p.153 · 16화)tgdba Performance Improvement Methods (01화) · tgdba Measuring Database Performance (01 · 16화)

제4조 컬럼을 가공하지 않는다 ​

형변환과 함수는 리터럴 · 바인드 쪽에서 처리한다. 컬럼을 가공하면 인덱스와 통계를 함께 잃는다. SQL을 고칠 수 없으면 함수 기반 인덱스나 가상 컬럼을 쓴다(T2를 거친다).

근거 리포트성능고도화공식문서
T1 1호 (02화 · TO_CHAR(ORD_DT): 힌트를 줘도 FULL 5,826 · E-Rows 2,500) · T1 2호 (03화 · 숫자 리터럴과 비교한 문자 컬럼 5 → 1,406 · 날짜가 VARCHAR2(8))II권 Ch1 03절 「인덱스 사용이 불가능한 경우」 · 04절 「함수 기반 인덱스 · 가상 컬럼」 (02 · 03화)tgsql Optimizer Access Paths (02화) · sqlrf Data Type Comparison Rules (03화)

제5조 '이 데이터에서 같다'를 '맞다'로 읽지 않는다 ​

고친 SQL은 원장(업무 정의를 가장 단순하게 쓴 SQL)과 대조하고, 경계 데이터를 복사본에 만들어 대조한다(정합성 회귀 체크리스트 A~H). 직전 판과만 대조하면 직전 판이 빠뜨린 것은 끝내 보이지 않는다.

근거 리포트성능고도화공식문서
T1 1호 (02화 · T_ORD_BIG은 전부 자정이라 BETWEEN이 통과 · T_ORD에서 137건 34,159,700원) · T1 2호 + 정합성 이상 보고 (03화 · 0 패딩 누락 36,290건 / 297,291,000원) · T1 6호 (08화 · 평가 수가 다 50이라 순위가 같았다 · 금액 50배) · T3 2호 (15화 · 직전 판과 대조하면 99,850 = 99,850으로 '통과' · 원장과 대조하니 170건) · T1 11호 (15b화 · 같은 날 오후의 대조 100,000 = 100,000 · 경계 시각에서 100,001 vs 100,000)II권 Ch4 01절 「쿼리 변환이란」 (p.462) · 02절 「서브쿼리 Unnesting」 (p.466 · 08화)tgsql Query Transformations (08화)

제6조 행마다 건너가는 일은 횟수로 적는다 ​

한 번의 값이 작아도 횟수 × 한 번만큼 시간이 든다. NL의 Starts, 스칼라 서브쿼리, 루프 안의 SQL, 행마다 호출하는 함수, 클릭마다 일어나는 하드 파싱이 그렇다. 리포트에 횟수를 적는다(Starts · recursive calls · 함수 본문 실행 수 · parse count).

근거 리포트성능고도화공식문서
T1 4호 (06화 · inner Starts 1,000,000 · 1,026,849 → 5,869) · T1 5호 (07화 · CBC 래치 1,035,706번 · 고객명 스칼라 Starts 752,995) · T3 1호 (14화 · 인덱스 셋을 행마다 · redo 916.6MB) · T3 2호 (15화 · recursive calls 301,187 → 2,457 · 함수 100,020 → 2,000)II권 Ch2 01절 NL 조인 (p.210 · 06화) · I권 05장 Call 통계 · User Call vs Recursive Call (p.346 · 349 · 09 · 15화) · I권 「PL/SQL 함수의 특징과 성능 부하」 (p.392 · 15화)tgsql Joins (06화) · lnpls PL/SQL Optimization and Tuning (15화)

제7조 통계는 관리하는 설정이다 — 그리고 계획은 지킬 수 있다 ​

옵티마이저는 데이터가 아니라 통계를 본다. 통계를 누가 · 언제 · 무엇으로 모으는지 통계 수집 정책서에 적는다. 적재나 통계가 바뀌어도 계획이 흔들리면 안 되는 문장은 SQL Plan Baseline으로 지키고, 새 계획은 EVOLVE(실행 검증)를 통과한 뒤에만 받아들인다(18화 실측: 빈 테이블 통계에서도 HASH 5,868 유지 · 베이스라인을 끄면 NL 1026K · 그 NL은 진화에서 0.33배로 탈락).

근거 리포트성능고도화공식문서
T1 8호 (10화 · 빈 테이블 통계 → Q2 5,868 → 1,026,852 · Q1 91 → 27,274) · T3 1호 (14화 · APPEND 온라인 통계는 히스토그램을 모으지 않는다: FREQUENCY → NONE) · T1 9호 (11화 · 히스토그램 + 바인드 · FORCE가 첫 손님 값으로 계획을 묶었다)II권 Ch3 03절 「옵티마이저의 한계」 (p.385 ~ 387) · 08절 「통계정보 II」 (p.442 ~ 459 · 10화)tgsql Optimizer Statistics Concepts (10 · 14화) · tgsql SQL Plan Management (장) · arpls DBMS_SPM (원천지도 18화 줄)

제8조 처방은 코드의 모양이 아니라 패턴으로 고른다 ​

같은 처방(N건마다 COMMIT, 채번 테이블, 한 문장으로)도 한 배치에서는 안전하고 다른 배치에서는 장애가 된다. 읽기와 쓰기를 떼어 놓는다. 채번은 업무 트랜잭션에서 떼고, 긴 커서는 그 커서가 읽는 테이블의 커밋에서 뗀다. 커밋은 커밋 주기 기준의 경로 번호로 적는다.

근거 리포트성능고도화공식문서
T4 1호 (12화 · 강도현이 접어 둔 채번 테이블을 다시 펼쳤다 · 316~321cs 대기) · T4 2호 = T1 10호 (13화 · '트랜잭션을 짧게'를 읽으면서 고치는 배치에 적용 → ORA-01555 · 반쯤 반영) · T3 1호 (14화 · P1 1,000건 커밋 → 화면에 정산이 반만 보임) · T3 2호 (15화 · 12화 처방을 그대로 얹은 보정 배치)I권 02장 「일련번호 채번 동시성 높이기」 (p.122) · Enqueue Lock · TX Lock (p.126 · 130 · 12화) · I권 Ch1 후반 Undo · 블록 클린아웃 · CR (p.41 · 46 · 54 · 58 · 13화)cncpt Data Concurrency and Consistency (12 · 13화) · sqlrf COMMIT (13화)

제9조 서버 스위치 · 자원 증설 제안에는 "무엇을 재 보라"로 답한다 ​

PGA, CPU, CURSOR_SHARING, 바인드 피킹 같은 인스턴스 스위치는 어느 문장이 그 덕을 보고 어느 문장이 망가지는지 가리지 못한다. 제안이 오면 ① 그 설정으로 줄어드는 몫(예: CPU를 기다린 % DB time)을 먼저 재고, ② 내 세션에서만 켜서 일부러 계획을 갈라 둔 문장을 찾아 잰다.

근거 리포트성능고도화공식문서
T1 7호 (09화 · PGA를 올리면 멈추는 페이지가 뒤로 밀릴 뿐 · Buffers 5,826 그대로) · T1 9호 (11화 · FORCE: 취소 탭 5,826 → 50,347 · 피킹 끄기: 2페이지 1,005,991) · T5-001 (16화 · CPU를 늘려 줄어드는 것은 CPU 대기 25.1% · 23.8%뿐)II권 Ch5 07절 「Sort Area 크기 조정」 (p.615 ~ 620 · 09화) · I권 「Cursor_Sharing」 (p.502 · 11화)tgdba Tuning the Program Global Area (09화) · tgsql Improving Real-World Performance Through Cursor Sharing (11화) · refrn Initialization Parameters (09 · 11 · 16화)

제10조 도구의 권고는 가설이다 ​

ADDM, SQL Tuning Advisor, SQL 프로파일, 자동 진화가 내놓는 권고문은 검사필증이 아니다. 채택하기 전에 ① 권고가 기댄 칸(Rationale · 시간 모델)을 표본으로 다시 세고, ② 권고를 적용한 뒤 T0로 다시 재고, ③ 그 해결책이 무엇을 숨기는지(코드에 남은 힌트 · 팩 의존 · 계획 고정) 적는다.

근거 리포트성능고도화공식문서
T5-001 (16화 · ADDM 요약 1위 Sequence Usage: 근거 줄이 SQL 경과 시간과 230배 어긋남) · T5-002 (17화 · 권고(CACHE 1000)대로 해도 DB time 900.7 → 902.2초 · 같은 권고를 다시 냄 · Row Lock은 Rationale이 ASH와 100% 일치해 채택) · T1 13호 (18화 · STA '예상 이득 99.42%' 프로파일 = 힌트를 무시하라는 두 줄 · 팩을 끄면 1026K로 돌아감 → 기각)좌표 미확인tgdba Automatic Performance Diagnostics (17화) · tgsql SQL Tuning Advisor (sql-tuning-advisor.html · 원천지도 18화 줄)

제11조 리스크와 롤백 칸을 비우지 않는다 — 그 일을 할 사람이 읽는 곳에 쓴다 ​

비워 둔 리스크 칸은 다음 장애가 된다. 적었더라도 구현하는 사람이 읽지 않는 문서에만 있으면 비운 것과 같다. 개발자에게는 코딩 가이드와 PR 체크리스트로, 배치 담당에게는 T3의 칸으로 옮긴다.

근거 리포트성능고도화공식문서
T4 1호 (12화 · 재발방지 2번 N건마다 COMMIT의 리스크 칸이 비었다) → T4 2호 (13화 · 그 처방이 ORA-01555를 냄) · T1 7호 (09화 · 포스트잇 값을 문자열로 붙이면 페이지마다 다른 SQL: 리스크 칸에 적었다) → T1 9호 (11화 · 개발팀은 리포트가 아니라 실습 스크립트를 베꼈다 · 하드 파싱 30,431)좌표 미확인좌표 미확인

제12조 바꾸는 것의 영향 범위를 적는다 ​

카디널리티를 바꾸는 변경(PK · 다건 허용 · 코드 재적재), 적재 순서를 바꾸는 이관, 보관 정책, '버그 수정'이라며 공지 없이 나가는 반영이 있으면 그 테이블을 읽는 SQL 전부를 회귀 대상에 올린다(체크리스트 H).

근거 리포트성능고도화공식문서
T1 6호 (08화 · 2020-02 평가 다건 허용 커밋에 Q3가 빠졌다) · T4 1호 (12화 · 버그 수정이라는 이유로 동시 시험 · 공지 없이 반영) · T2-001 (04화 · 이관 때 적재 순서가 바뀌어 CF 22,223 → 999,958) · T1 3호 (05화 · 보관을 DELETE로만 처리: 3,602 → 3,602)II권 Ch1 05절 클러스터링 팩터 (04화) · I권 Ch1 · Ch6 고수위선 (05화)tgsql Optimizer Access Paths (04화) · cncpt Logical Storage Structures (05화)

제13조 요구도 늙는다 — 원문을 다시 묻는다 ​

화면, 감사, 마케팅의 요구는 처음 정한 사람이 떠나면 이유도 같이 떠난다. SQL이 요구 때문에 바닥에 붙어 있으면 요구의 원문을 찾아 화면 주인에게 다시 묻는다(화면 요구 재협상서).

근거 리포트성능고도화공식문서
T1 7호 + 재협상서 1호 (09화 · 아무도 안 보던 총건수 · 11,652 → 약 15) · T4 1호 (12화 · 감사 원문은 '결번 금지'가 아니라 '결번 사유 기록')I권 05장 「페이지 처리의 중요성」 (p.389 · 09화)좌표 미확인

제14조 에러 없이 사라지는 것을 센다 ​

WHEN OTHERS THEN NULL, 반쯤 반영된 커밋, 오류 없이 끝난 배치를 경계한다. 정상 종료가 곧 결과가 맞다는 뜻은 아니다. 배치는 원장 = 처리 + 반송이 맞는지 센다. 예외는 사유와 함께 반송함에 남긴다.

근거 리포트성능고도화공식문서
T3 2호 (15화 · 에러 로그는 깨끗했는데 170건이 사라짐: 탈퇴 고객 150 · 미확정 20) · T4 2호 (13화 · ORA-01555 시점까지만 반영 50,000 / 50,000) · T3 1호 (14화 · 1,000건마다 커밋하는 동안 화면에 정산이 반만 보임)좌표 미확인sqlrf INSERT (error_logging_clause) · arpls DBMS_ERRLOG (15화)

제15조 인자로 들어오지 않는 입력은 인자로 꺼낸다 ​

시계(SYSDATE), 세션 시간대, NLS, 세션 상태에 기대는 코드는 같은 인자에도 다른 답을 낸다. 그런 입력은 인자로 꺼내고, 결과 캐시와 DETERMINISTIC은 답이 테이블과 인자에만 기댈 때만 붙인다.

근거 리포트성능고도화공식문서
T1 2호 (03화 · NLS가 DD-MON-RR이면 27,390건 · YYYY-MM-DD면 에러 없이 1,000,000건) · T1 11호 (15b화 · 결과 캐시가 정산일을 6/14로 고정 · 6/14 17:30 ~ 6/17 09:40)I권 「Result 캐시」 (p.472) · 「Deterministic 함수 사용 시 주의사항」 (p.512 · 15b화)lnpls PL/SQL Subprograms (PL/SQL Function Result Cache) · DETERMINISTIC Clause (15b화) · nlspg Setting Up a Globalization Support Environment (03화)

제16조 팩 라이선스 확인란을 채운다 ​

진단 팩(AWR · ASH · ADDM)이나 튜닝 팩(SQL Monitor · STA · SQL 프로파일)을 쓰는 작업과 리포트에는 에디션 · CONTROL_MANAGEMENT_PACK_ACCESS · 계약 여부를 적는다(§4 서식).

  • NONE은 막아 주지 않는다. AWR 리포트, ASH 리포트, DBA_HIST_* 조회는 그대로 열린다. 라이선스는 설정이 아니라 계약으로 지킨다(17화).
  • 튜닝 팩이 꺼지면 받아 둔 SQL 프로파일은 에러 없이 무시된다(18화 실측: DIAGNOSTIC · NONE에서 Q2 rev00이 5,869 → 1026K). 팩에 기대는 해결책은 해결책이라기보다 계약의 일부다. 코드로 고칠 수 있으면 코드로 고친다. SPM 베이스라인은 팩 기능이 아니다(NONE에서도 쓰였다).
근거 리포트성능고도화공식문서
T5-002 (17화 · SE2 서버에서 습관처럼 awrrpt · NONE에서 막힌 것 셋 · 막히지 않은 것 넷) · T1 13호 (18화 · 프로파일이 팩 설정 하나로 사라진다)좌표 미확인dblic Licensing Information (16 · 17화) · refrn Initialization Parameters: CONTROL_MANAGEMENT_PACK_ACCESS (16 · 17화)

2. 대기 줄 — 근거 1회 (조문이 아니다 · 다음 재발에 올린다) ​

후보낸 화근거 (1회)지금 어디에 남나올라가는 날
화면이 고르는 값은 바인드로 · 코드값은 상수 리터럴로 · 엿보지 못해도 같은 계획이 나오는 모양 (코딩 가이드 1 ~ 6)11T1 9호코딩 가이드 v1.0 「대기 조문」 · 체크리스트 A · B리터럴 이어 붙이기 · FORCE 제안이 다른 리포트에서 다시 나올 때
날짜 범위는 >= 시작 AND < 다음 구간 (가이드 7)02T1 1호 (03화는 VARCHAR2(8)에서 BETWEEN이 맞는 반례)가이드 대기 조문 · 체크리스트 B시분초가 있는 날짜의 BETWEEN이 다른 리포트에서 다시 나올 때. 졸업 과제의 ECOMMERCE가 그 후보다
조인 상대가 그 키로 정말 한 줄인가 (가이드 9)08T1 6호가이드 대기 조문 · 체크리스트 B (정합성 D)1 쪽이 하나가 아닌 조인이 다시 나올 때. 졸업 과제가 그 후보다
페이징은 키 기반 · 정렬 키는 유일하게 (가이드 10)09T1 7호가이드 대기 조문깊은 페이지 · 정렬 키 중복이 다시 나올 때
적재 방식을 배치 머리에 적는다 · APPEND면 LOAD AS SELECT를 확인한다14T3 1호T2 v2 「3-2 적재 비용」 · T3 2번 칸에 이미 들어 있다—
FORALL에는 묶이는 문장을 · ERROR_INDEX는 첨자가 아니다15T3 2호가이드 대기 조문—
한 시간 리포트로 현업의 '몇 분'을 기각하지 않는다17T5-002제1조 세칙으로 흡수(원인이 '평균을 결론으로'와 같다)—
이관할 때 ORDER BY로 적재 순서를 지킨다04T2-001제12조의 예—
지난 결론을 지우지 않고 옆에 정정한다 (교차검증판)17(원인이 아니라 방법)§5 문서 운용조문이 될 수 없다. 운용 규칙으로 둔다

조문을 아끼는 것이 아니다. 두 번 나온 것은 구조이고, 한 번 나온 것은 사건이다. 사건을 조문으로 만들면 표준이 그날의 기분을 따라 자란다.


3. 코드 리뷰 체크리스트 — PR마다 (Y / N / N-A) ​

리뷰어는 N이 하나라도 있으면 이유 칸을 채우게 하고 머지를 미룬다. N-A는 이유를 같은 칸에 쓴다(빈칸과 다르다).

A. 계획 — 재고 왔는가 (제1 · 2 · 3조) ​

#묻는 것YNN/A
A1예상 계획(EXPLAIN PLAN)만이 아니라 실제 실행계획(ALLSTATS LAST)을 첨부했는가
A2access와 filter를 구분해 적었는가
A3E-Rows와 A-Rows가 10배 넘게 어긋난 줄을 짚었는가(어긋났다면 통계 정책서 SOP)
A4효과를 Buffers N → M 형식으로 적었는가 · 그 숫자의 조회 범위(행수 · 선택도)를 옆에 적었는가
A5Buffers가 같다면 바뀐 값(CPU 10회 합 · TEMP 패스 · 결과)을 같은 조건으로 적었는가
A6측정 조건(캐시 · statistics_level · 데이터 규모 · 부하 프로파일 ID)과 운영과 다른 점을 적었는가

B. 정합성 — 맞는가 (제5 · 14 · 15조) ​

#묻는 것YNN/A
B1원장(업무 정의를 가장 단순하게 쓴 SQL)과 건수 · 합계 · 양방향 MINUS · 중복 키를 대조했는가
B2잘라 내기 전(TOP N · 페이징을 뗀) 전체로 대조했는가
B3조인마다 '1 쪽'이 그 키로 정말 하나인지 · 1 쪽에 없는 키(고아)가 있는지 봤는가
B4경계(시분초 · NULL · 0 패딩 · 시각 · 세션)를 복사본에 만들어 대조했는가
B5예외를 삼키지 않는가(WHEN OTHERS THEN NULL 없음) · 배치라면 '원장 = 처리 + 반송'을 확인했는가
B6시계 · NLS · 세션 상태에 기대는 곳이 있으면 인자로 꺼냈는가 · 결과 캐시 · DETERMINISTIC이 거짓 약속이 아닌가

C. 변경 — 무엇을 바꾸나 (제4 · 7 · 12조) ​

#묻는 것YNN/A
C1인덱스 · 힌트를 더하거나 빼면 T2 승인서를 붙였는가(INVISIBLE 먼저 · 적재 비용 3-2 · 손익분기)
C2힌트를 붙였다면 힌트 유효기간 대장에 그때의 규모와 재검토 조건을 적었는가
C3컬럼을 가공하지 않았는가(형변환은 리터럴 · 바인드 쪽)
C4그 테이블을 읽는 SQL 전부를 회귀 대상에 올렸는가(카디널리티 · 적재 순서 · 통계 · 보관 정책 변경)
C5계획이 흔들리면 안 되는 문장이면 SPM 베이스라인 · 진화 절차를 적었는가

D. 배치 — 창 안에 · 안전하게 (제6 · 8조) ​

#묻는 것YNN/A
D1루프 안의 SQL · 행마다 호출하는 함수의 횟수를 적었는가(recursive calls · 함수 본문 실행 수)
D2커밋 주기를 커밋 주기 기준의 경로 번호로 적었는가 · fetch across commit이 아닌가
D3대량 DML의 redo · undo를 재거나 추정했는가(적재 방식과 함께)
D4낮과 겹치면 무엇이 막히는지(T3 7번) 적었는가 · 리소스 매니저에 기대면 그 장비에서 잰 값인가

E. 운영 — 되돌릴 수 있는가 (제11 · 16조 · 마지막 조항) ​

#묻는 것YNN/A
E1롤백 절차가 있는가(명령 · 소요 · 되돌릴 수 없는 것)
E2리스크를 그 일을 할 사람이 읽는 곳(이 PR · 코딩 가이드 · T3)에 적었는가
E3진단 · 튜닝 팩을 쓰면 팩 라이선스 확인란을 채웠는가 · 해결책이 팩에 기대지 않는가
E4재측정 계획(지표 · 주기 · 사건으로 쓴 재검토 조건)이 있는가
E5이 결정에 그 당시의 데이터 규모와 근거 수치가 함께 적혀 있는가

4. 팩 라이선스 확인란 (제16조의 서식) ​

항목적는 것18화 연습 DB
에디션V$VERSION 첫 줄Oracle AI Database 26ai Free 23.26.2
CONTROL_MANAGEMENT_PACK_ACCESS메모리 · spfile 값DIAGNOSTIC+TUNING · DIAGNOSTIC+TUNING
계약진단 팩 · 튜닝 팩 계약 여부Free: 둘 다 포함
이 작업이 쓰는 팩 기능AWR · ASH · ADDM (진단) / SQL Monitor · STA · SQL 프로파일 (튜닝)AWR · ADDM · STA · 프로파일
팩이 꺼지면 이 해결책은막힌다 / 조용히 무시된다 / 상관없다프로파일: 조용히 무시 (Q2 rev00 5,869 → 1026K) · SPM 베이스라인: 상관없다
팩이 없는 서버라면대신 쓰는 도구Statspack · 블로킹 트리 주기 저장 · 코드로 고친다

5. 문서 운용 (조문이 아닌 규칙) ​

규칙왜
지난 결론을 지우지 않고 옆에 정정한다. 1호를 고치지 않고 2호에서 1호의 칸 옆에 정정을 적는다(17화 T5-002 교차검증판 · 18화 W01 2열)무엇이 왜 틀렸는지 남아 있어야 다음 사람이 같은 칸에서 같은 결론을 내리지 않는다
조문의 근거가 된 리포트가 정정되면 그 조문의 각주에 정정본 번호를 덧붙인다근거가 틀렸던 조문을 모르고 지키지 않게
대기 줄의 후보에 두 번째 근거가 생기면 그날 조문으로 올리고 개정 이력에 적는다승격 규칙을 표준 자신에게도 적용한다
이 표준의 전제: 연습 DB 26ai Free 23.26.2 · cpu_count 2 · 한빛유통 데이터 규모(주문 100만 · 고객 2,000) · 18주의 리포트표준도 그때의 규모에서 나왔다. 전제가 바뀌면 다시 센다(마지막 조항을 표준 자신에게도 적용한다)

마지막 조항 (고정) ​

모든 성능 결정에 그 당시의 데이터 규모와 근거 수치를 함께 적는다. ​

강도현이 하지 않은 단 한 가지가 이것이다. 그는 이유를 남겼다(커밋 로그). 숫자도 남겼다(2018-11-06 회의록 본문 "3초 → 0.4초"). 규모도 남겼다(그 회의록 첨부의 맨 끝 줄 "※ 측정 조건 : 운영 DB 복제본, 주문 20,000 건"). 그가 하지 않은 것은 그 셋을 함께, 다음 사람이 보는 자리에 적는 것이었다. 소스에는 "-- 건드리지 말 것 (2018.11 강도현)" 한 줄뿐이었고, 언제 다시 잴지는 어디에도 없었다.

합격증의 '합격'은 정격하중, 정원, 유효기간과 함께 한 장에 적혀 사람이 타는 문 옆에 걸려 있을 때만 의미가 있다(18화 1층 엘리베이터 홀).

근거 리포트성능고도화공식문서
T2-001 (04화 · "RANGE SCAN으로 변경 완료": 측정 수치가 한 줄도 없는 바인더) · T1 4호 + 대장 1호 (06화 · 회의록 본문에 2만 건이 없었다) · T1 6호 (08화 · 평가 다건 허용 때 '1 쪽'이라는 전제가 깨졌다) · T1 7호 (09화 · 총건수 요구의 이유가 떠났다) · T1 8호 (10화 · "적재 직후 통계 수집"에서 '언제'를 아무도 읽지 않았다) · T4 1호 (12화 · "매기는 곳이 하나뿐"이라는 전제) · T1 11호 (15b화 · "DETERMINISTIC"을 재지 않고 믿었다) · T1 12호 (18화 · "3배 빨라졌습니다": 수치 없는 초안)좌표 미확인tgdba Performance Improvement Methods (01화) · tgsql Influencing the Optimizer (06화: 힌트는 그 시점의 데이터에 대한 판단)

개정 이력 ​

판화무엇이 바뀌었나
v1.018화제정. 조문 16(근거 2회 이상만) · 대기 줄 9 · 코드 리뷰 체크리스트 26문 · 팩 라이선스 확인란 · 문서 운용 4 · 마지막 조항. SQL 코딩 가이드 v1.0과 함께 냈다(가이드는 SQL을 쓰는 사람의 문서, 이 표준은 튜너와 리뷰어의 문서)

자매 문서: T0 측정규약 · T9 선정 기준 · SQL 코딩 가이드 v1.0 · 정합성 회귀 체크리스트 · 진단 도구 4열 대응표 · W01 베이스라인 원장 · 리비전 대장