Skip to content
튜닝 연습옵티마이저와 통계
OPT-016

5년 만에 통계를 다시 모으자는데 핵심 화면 여섯 개가 어떻게 바뀔지 모른다

실전PLSQL유통606 / 700

상황 ​

본사 레거시 DB는 2016년에 자동 통계 수집을 끄고, 손으로 적은 목록만 밤마다 모아 왔다. 점검해 보니 PUP 스키마 18개 테이블 가운데 7개의 통계가 2019년 3월 이관 때의 것이다. 선배는 오늘 밤 모두 다시 모으고 자동 수집도 켜자고 했다. 본사 IT 팀장의 조건은 이렇다. "계획이 바뀌는 화면이 있으면 미리 알려 주고, 문제가 생기면 바로 되돌릴 수 있어야 합니다." 조민우는 어제 03:00의 운영 사본(복사본)에서 먼저 다시 모아 핵심 SQL 여섯 개를 돌려 보았다.

테이블과 인덱스 ​

  • PUP 스키마 18개 테이블 · 통계가 2019-03의 것인 테이블 7개: CF02 · CF05 · CF07 · CF11(실제 1,096,708행 · 통계 109,860) · CF12 · CF13 · CF15
  • 핵심 SQL 여섯 개: 화면 S1 ~ S4, 배치 S5와 S6 (빈도는 아래 표)
  • 통계 이력 보존 31일 · PUBLISH 기본값 TRUE · 자동 통계 수집 꺼짐

원본 SQL ​

sql
-- 선배의 첫 안 (오늘 밤 23:00)
BEGIN
  DBMS_STATS.GATHER_SCHEMA_STATS(ownname       => 'PUP',
                                 options       => 'GATHER',
                                 no_invalidate => FALSE);
  DBMS_AUTO_TASK_ADMIN.ENABLE('auto optimizer stats collection', NULL, NULL);
END;
/

실행계획 학습용 예시 ​

xplan
[복사본(어제 03:00 운영 사본)에서 18개를 다시 모은 뒤 · 핵심 SQL 여섯 개 · 같은 바인드 값]
 SQL  무엇 (하루 빈도)                  지금 계획                 Buffers   다시 모은 뒤 계획            Buffers
 S1   점장 「어제 상품별 판매」 (600)     HASH JOIN · CF11 FULL       8,215   NL · CF11_PK                     389
 S2   「일별 판매 건수」 (3,000)           INDEX RANGE SCAN                5   그대로                             5
 S3   「상품 판매 순위」 (40)              HASH JOIN · CF11 FULL       8,210   그대로                         8,210
 S4   「발주 진행」 (2,000)                NL · CF13_PK                   38   HASH JOIN · CF13 FULL             61
 S5   「입출고 대사」 배치 (1)             NL · CF15_PK                1,410   HASH JOIN · CF15 FULL            406
 S6   「일 재고 마감」 배치 (1)            INDEX RANGE SCAN                4   그대로                             4

 · 복사본은 하루 전 데이터이고, 운영의 바인드 값 분포와 공유 풀 상태를 그대로 갖고 있지 않다.
 · 복사본에서 18개를 모으는 데 41초 · 공유 풀의 PUP 커서 약 2,100개

문제 ​

  1. 선배의 첫 안을 그대로 돌릴 때의 위험을 두 가지 이상 쓰시오.
  2. 운영에서 새 통계를 공개하기 전에 미리 보고, 고른 시각에 공개하고, 문제가 생기면 되돌리는 절차를 SQL로 쓰시오.
  3. S4처럼 일량이 조금 늘어나는 SQL을 어떻게 판단하고 기록할지 쓰시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자