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

인덱스를 더 만든 적이 없다는데 정산 적재의 redo가 두 달 새 두 배가 됐다

중급INSERT한빛유통149 / 700

상황 ​

야간 정산 배치는 매일 01:00에 T_ORD_STLM을 비우고 T_ORD에서 10만 건을 직접 경로로 다시 채운다. 두 달 전에는 적재 단계가 0.9초, redo 23MB였는데 지금은 1.8초, 51MB다. 운영은 ARCHIVELOG라 아카이브 로그도 그만큼 늘었다. 오과장은 이렇게 말한다. "적재 SQL도 건수도 그대로다. 화면에서 쓰는 인덱스도 두 개 그대로라고 들었다." 알아보니 조민우가 두 달 동안 「고객 정산 내역」과 「일자별 대사」를 튜닝하며 인덱스를 여러 개 만들어 재 보았고, 쓰지 않기로 한 것은 지우지 않고 INVISIBLE로 돌려 두었다.

테이블과 인덱스 ​

  • T_ORD_STLM 정산: 100,000행 · 640블록 · 매일 TRUNCATE 뒤 INSERT /*+ APPEND */ … SELECT로 다시 채운다 · 낮에는 읽기만 한다 · 테이블과 인덱스는 LOGGING이다
  • 인덱스 다섯 개(아래 USER_INDEXES) · 화면이 쓰는 것은 IX_STLM_CUS_DT(「고객 정산 내역」)와 IX_STLM_DT(「일자별 대사」)다
  • 「일자별 고객 정산」 SQL에는 9월에 조민우가 IX_STLM_DT_CUS를 재 보며 붙인 /*+ INDEX(s IX_STLM_DT_CUS) */ 힌트가 그대로 남아 있다
  • 「정산 리포트」 배치(매일 05:00)는 소스 첫머리에서 ALTER SESSION SET OPTIMIZER_USE_INVISIBLE_INDEXES = TRUE를 실행한다 · 9월에 조민우가 숨긴 인덱스를 재 보려고 넣은 줄이다

원본 SQL ​

sql
-- 야간 정산 배치 · 01:00 · 적재 단계
TRUNCATE TABLE T_ORD_STLM;

INSERT /*+ APPEND */ INTO T_ORD_STLM (STLM_SEQ, ORD_SEQ, CUS_ID, STLM_DT, STLM_AMT)
SELECT ROWNUM, ORD_SEQ, CUS_ID, ORD_DT, ORD_AMT
  FROM T_ORD;
COMMIT;

실행계획 학습용 예시 · 인덱스당 적재 비용은 교재 04화 · 14화 실측 비례 ​

xplan
[적재 단계 · T_ORD_STLM 10만 건 · 배치 로그]
              인덱스 (VISIBLE / INVISIBLE)   경과     redo
  8월 26일    2 / 0                          0.9초    23.1MB
  9월 23일    2 / 2                          1.5초    41.2MB
  10월 28일   2 / 3                          1.8초    50.6MB

[USER_INDEXES · T_ORD_STLM]
INDEX_NAME        COLUMNS                VISIBILITY  LEAF_BLOCKS  만든 달
----------------  ---------------------  ----------  -----------  -------
IX_STLM_CUS_DT    (CUS_ID, STLM_DT)      VISIBLE             392  6월
IX_STLM_DT        (STLM_DT)              VISIBLE             270  6월
IX_STLM_DT_CUS    (STLM_DT, CUS_ID)      INVISIBLE           392  9월
IX_STLM_CUS_AMT   (CUS_ID, STLM_AMT)     INVISIBLE           315  9월
IX_STLM_ORD_AMT   (ORD_SEQ, STLM_AMT)    INVISIBLE           250  10월

[DBA_INDEX_USAGE · 9월 29일 ~ 10월 28일]
IX_STLM_CUS_DT 181,220 · IX_STLM_DT 9,410 · IX_STLM_DT_CUS 0 · IX_STLM_CUS_AMT 30 (LAST_USED 10/28 05:01) · IX_STLM_ORD_AMT 0

[V$SQL · IX_STLM_CUS_AMT를 쓰는 SQL · MODULE STLM_REPORT]
SELECT CUS_ID, SUM(STLM_AMT) FROM T_ORD_STLM GROUP BY CUS_ID
---------------------------------------------------------------------------------------------------------
| Id  | Operation             | Name            | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
---------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |                 |      1 |        |   2000 |00:00:00.02 |     322 |
|   1 |  HASH GROUP BY        |                 |      1 |   2000 |   2000 |00:00:00.02 |     322 |
|   2 |   INDEX FAST FULL SCAN| IX_STLM_CUS_AMT |      1 |   100K |   100K |00:00:00.01 |     322 |
---------------------------------------------------------------------------------------------------------

문제 ​

  1. 적재 SQL도 건수도 그대로인데 redo와 시간이 늘어난 이유를 배치 로그와 USER_INDEXES로 설명하시오. 숨긴 인덱스 하나가 적재에 더하는 비용도 어림하시오.
  2. 숨긴 인덱스 셋을 각각 어떻게 할지 정하시오. 힌트가 남아 있는 IX_STLM_DT_CUS와 사용 이력이 30번인 IX_STLM_CUS_AMT는 근거를 따로 쓰시오.
  3. 판정에 맞는 정리 절차를 SQL로 작성하시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자