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

이관 대사의 건수 확인 한 줄이 인덱스만 읽는데 3초 가까이 걸린다

기초SELECT유통110 / 700

상황 ​

본사는 매일 밤 판매상품(CF11)을 정보계로 옮긴 뒤, 원천 건수와 옮긴 건수를 맞춰 보는 대사 스크립트를 돌린다. 그 가운데 건수를 세는 단계 하나가 매일 3초 가까이 걸려 야간 작업표에서 눈에 띈다. 스크립트를 쓴 조민우는 이렇게 말했다. "테이블이 크니까 인덱스로 세라고 힌트를 넣었다." 아래는 이관 직후, 버퍼 캐시에 인덱스 블록이 거의 없을 때 잰 값이다.

테이블과 인덱스 ​

  • CF11 판매상품: 1,096,708행 · 8,204블록 · 컬럼은 모두 NOT NULL
  • 인덱스 CF11_PK (SLE_NO, ITM_NO): BLEVEL 2 · 리프 약 4,290블록 · 통계 최신 · 다른 인덱스 없음
  • db_file_multiblock_read_count = 128(교재 04화 실측 환경과 같다)
  • 이관 작업은 테이블 블록만 읽으므로, 대사 단계가 시작될 때 인덱스 블록은 거의 디스크에 있다

원본 SQL ​

sql
SELECT /*+ INDEX(b CF11_PK) */ COUNT(*)
  FROM CF11 b

실행계획 학습용 예시 · 멀티블록 읽기 단위는 교재 04화 실측 환경 ​

xplan
--------------------------------------------------------------------------------------------
| Id  | Operation        | Name    | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads |
--------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |         |      1 |        |      1 |00:00:02.84 |    4293 |  4291 |
|   1 |  SORT AGGREGATE  |         |      1 |      1 |      1 |00:00:02.84 |    4293 |  4291 |
|   2 |   INDEX FULL SCAN| CF11_PK |      1 |   1096K|   1096K|00:00:02.71 |    4293 |  4291 |
--------------------------------------------------------------------------------------------

[세션 통계 · 대기 이벤트 — 같은 실행]
  physical read total IO requests              4,291
  physical read total multi block requests         0
  db file sequential read                      4,291회 · 2.6초

문제 ​

  1. Buffers는 4,293블록으로 인덱스 크기만큼인데 2.8초가 걸리는 이유를 INDEX FULL SCAN이 블록을 읽는 방식과 세션 통계로 설명하시오.
  2. 결과(전체 건수)를 바꾸지 않고 같은 인덱스를 더 빨리 읽도록 SQL을 고치시오. 고친 뒤 Buffers와 I/O 요청 수가 각각 어떻게 달라지는지도 설명하시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자