Skip to content
튜닝 연습인덱스 스캔 효율과 테이블 액세스
ACC-063

매주 인덱스를 전부 다시 만드는 정비 작업을 없애려 하자, 그래야 인덱스가 얕아진다는 반대가 나왔다

기초PLSQL한빛유통138 / 700

상황 ​

운영 DB에는 2019년 외주 DBA가 만든 「주간 인덱스 정비」 작업이 있다. 매주 일요일 01:00에 sqlp 스키마의 인덱스를 하나도 빼지 않고 REBUILD ONLINE으로 다시 만든다. 작업 설명서에는 "인덱스는 쓸수록 깊어지고 느려지므로 매주 다시 만들어 높이를 낮춘다"라고 적혀 있다. 새로 온 DBA가 근거 없는 정기 작업을 정리하겠다며 이 작업을 목록에 올리자 조민우가 반대했다. "다시 만들어야 인덱스가 얕아지고 월요일 화면이 빨라진다." 박팀장은 이 작업이 무엇을 주는지 숫자로 보자고 했다.

테이블과 인덱스 ​

  • T_ORD_BIG: 1,000,000행 · 5,826블록 · 운영에서는 주문이 계속 INSERT된다
  • IX_ORD_BIG_DT_AMT (ORD_DT, ORD_AMT): 「기간 매출」용(2024년 6월 한 달 91블록) · 새 주문의 항목은 늘 맨 오른쪽 리프에 들어간다
  • IX_ORD_BIG_CUS (CUS_ID): 「고객 요약」(COUNT(*), 고객당 500건)용 · 새 주문의 항목은 고객 2,000명 각자의 자리에 끼어든다
  • 정비 작업 한 번: 스키마 인덱스 23개(약 260MB) · 약 2분 30초 · redo 약 280MB(운영은 ARCHIVELOG라 그만큼 아카이브 로그가 쌓인다)
  • 이 스키마 인덱스의 브랜치 블록 하나는 아래 블록을 약 400개 가리킨다

원본 SQL ​

sql
-- 「주간 인덱스 정비」 (2019) · DBMS_SCHEDULER 작업 JOB_IDX_WEEKLY · 매주 일요일 01:00
BEGIN
  FOR r IN (SELECT index_name
              FROM user_indexes
             WHERE index_type = 'NORMAL') LOOP
    EXECUTE IMMEDIATE 'ALTER INDEX ' || r.index_name || ' REBUILD ONLINE';
  END LOOP;
END;

실행계획 학습용 예시 · 리프 블록 수는 교재 04화 실측 규모 ​

xplan
[USER_INDEXES · 정비 직전(일요일 00:55) → 직후(01:05)]
INDEX_NAME          BLEVEL    LEAF_BLOCKS        NUM_ROWS     CLUSTERING_FACTOR
------------------  --------  -----------------  -----------  ----------------------
IX_ORD_BIG_DT_AMT   2 → 2     3,214 → 3,206      1,000,000    999,999 → 999,999
IX_ORD_BIG_CUS      2 → 2     3,128 → 3,060      1,000,000    약 1,000,000 → 그대로
(다음 일요일 00:55에는 다시 3,214와 3,128 근처다. 넉 주 동안 같은 모양이 되풀이됐다)

[「고객 요약」 CUS_000123 · 정비 직전 토요일]
---------------------------------------------------------------------------------------------
| Id  | Operation         | Name           | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
---------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |                |      1 |        |      1 |00:00:00.01 |       4 |
|   1 |  SORT AGGREGATE   |                |      1 |      1 |      1 |00:00:00.01 |       4 |
|*  2 |   INDEX RANGE SCAN| IX_ORD_BIG_CUS |      1 |    500 |    500 |00:00:00.01 |       4 |
---------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("CUS_ID"=:V_CUS)

[정비 직후 월요일 · 같은 SQL]          INDEX RANGE SCAN · Buffers 4
[「기간 매출」 2024년 6월 · 직전 / 직후]  INDEX RANGE SCAN · Buffers 91 / 91

문제 ​

  1. 정비 직전과 직후의 BLEVEL과 LEAF_BLOCKS를 근거로, 이 작업이 인덱스 높이를 낮추지 못하는 이유를 설명하시오. 높이가 언제 하나 늘어나는지도 어림하시오.
  2. 「고객 요약」과 「기간 매출」의 Buffers가 정비 전후에 그대로인 이유를 설명하시오.
  3. 이 작업을 어떻게 할지 SQL로 작성하고, 인덱스를 다시 만드는 것이 맞는 경우를 쓰시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자