현재 선택한 SQL 과정

SQLP 이론 학습

이론 목록으로 돌아가기

Index·System Statistics: Access Path 비용을 만드는 입력값

BLEVEL·LEAF_BLOCKS·CLUSTERING_FACTOR와 CPU·Single/Multiblock I/O 특성이 Index와 Full Scan 비용 비교에 반영되는 원리를 이해합니다.

예상 읽기 22

핵심 요약

Optimizer는 Index의 존재 여부만으로 Access Path를 선택하지 않습니다. Index Statistics와 System Statistics를 사용해 다음 작업량을 예상합니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
B-tree Root·Branch 탐색
→ 조건 범위의 Leaf Block·Entry Scan
→ 후보 ROWID 생성
→ Heap Table Block 방문
→ Predicate·Join·Sort 처리

대표 입력값입니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Index Statistics
  BLEVEL
  LEAF_BLOCKS
  NUM_ROWS
  DISTINCT_KEYS
  AVG_LEAF_BLOCKS_PER_KEY
  AVG_DATA_BLOCKS_PER_KEY
  CLUSTERING_FACTOR

System Statistics
  CPUSPEEDNW·IOSEEKTIM·IOTFRSPEED
  CPUSPEED·SREADTIM·MREADTIM·MBRC
  MAXTHR·SLAVETHR

연결 흐름입니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Predicate Cardinality
+ Index 크기·Key 중복도·Table 배치
+ CPU·Single Block·Multiblock I/O 특성
→ 후보 Access Path·Join의 Cost
→ 최저 Cost Plan 선택

Cost는 실제 초 단위 실행시간이나 실제 I/O Call 수가 아닙니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Cost
  = 같은 SQL과 Optimizer 환경에서
    후보 Plan을 비교하기 위한 내부 예상 단위

이 이론의 범위

이 이론은 SQLP의 SQL 고급활용 및 튜닝 → SQL 옵티마이저 → Index·System Statistics와 Cost 범위에서 Access Path 비용을 구성하는 통계 입력값과 검증 절차를 다룹니다.


학습 목표

이 이론을 학습한 뒤에는 다음을 설명할 수 있어야 합니다.

  • BLEVEL, LEAF_BLOCKS, NUM_ROWS, DISTINCT_KEYS를 구분한다.
  • BLEVEL=0과 높은 BLEVEL의 의미를 정확히 설명한다.
  • AVG_LEAF_BLOCKS_PER_KEYAVG_DATA_BLOCKS_PER_KEY를 구분한다.
  • 복합 Index의 DISTINCT_KEYS가 전체 Key 조합 NDV임을 설명한다.
  • All-Key-NULL Row와 Index NUM_ROWS의 관계를 설명한다.
  • CLUSTERING_FACTOR가 Table Block 방문 Cost에 미치는 영향을 설명한다.
  • Global·Partition·Subpartition Index Statistics의 범위를 구분한다.
  • Noworkload와 Workload System Statistics의 수집 방식·우선순위를 설명한다.
  • SREADTIM·MREADTIM·MBRC가 수집되지 않을 수 있는 조건을 설명한다.
  • System Statistics 변경이 기존 Cursor를 무효화하지 않는 이유를 설명한다.
  • Cost와 실제 Runtime 지표를 함께 사용해 Access Path를 검증한다.

1. Index 경로의 비용 구성

Heap-Organized Table의 일반적인 B-tree Index 경로입니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
1. Root·Branch 수직 탐색
2. 시작 Leaf Block 도달
3. 조건 Range의 Leaf Entry Scan
4. 후보 ROWID 반환
5. ROWID가 가리키는 Table Block 접근
6. Table Filter·Projection·Join 처리

각 단계의 대표 통계 입력입니다.

단계주요 입력
Root·Branch 탐색BLEVEL
Leaf Range ScanLEAF_BLOCKS, Selectivity, Key 분포
동일 Key 중복 EntryAVG_LEAF_BLOCKS_PER_KEY
동일 Key Table Block 분산AVG_DATA_BLOCKS_PER_KEY
넓은 Range의 Table 배치CLUSTERING_FACTOR
후보 Row 수Table·Column·Histogram Statistics
I/O·CPU 환산System Statistics

따라서 Index 사용 여부보다 다음을 먼저 질문합니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
몇 개의 Leaf Block을 읽는가?
몇 개의 Entry·ROWID를 상위로 반환하는가?
ROWID가 몇 개의 Table Block을 방문하게 하는가?
Table Access를 Covering으로 제거할 수 있는가?
Full Scan의 Multiblock 경로가 더 저렴한가?

2. Index Statistics 조회

SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
SELECT index_name,
       index_type,
       blevel,
       leaf_blocks,
       num_rows,
       distinct_keys,
       avg_leaf_blocks_per_key,
       avg_data_blocks_per_key,
       clustering_factor,
       sample_size,
       last_analyzed
FROM   user_indexes
WHERE  table_name = 'ORDERS'
ORDER  BY index_name;

Partitioned Index는 별도 범위를 확인합니다.

SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
SELECT index_name,
       partition_name,
       blevel,
       leaf_blocks,
       num_rows,
       distinct_keys,
       avg_leaf_blocks_per_key,
       avg_data_blocks_per_key,
       clustering_factor,
       last_analyzed
FROM   user_ind_partitions
WHERE  index_name = 'ORDERS_DATE_LIX'
ORDER  BY partition_position;
CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Global Index Statistics
Partition Index Statistics
Subpartition Index Statistics

→ Query가 실제 접근하는 범위와 같은 Statistics 수준을 확인

3. BLEVEL

Oracle Dictionary의 공식 의미입니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
BLEVEL
  = Root Block에서 Leaf Block까지의 B-tree Level

중요한 기준입니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
BLEVEL = 0
  → Root Block과 Leaf Block이 같은 Block

BLEVEL = 1
  → Root 아래 Leaf Level이 존재

BLEVEL 증가
  → 한 번의 Probe에서 통과하는 Branch Level 증가 가능

BLEVEL을 Index의 전체 Block 수로 해석하지 않습니다.

3.1 BLEVEL이 높다고 즉시 Rebuild하지 않는다

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
단건 Probe 1회
  → 수직 탐색 Level 영향

대량 Range Scan
  → Leaf Scan·Table Access가 더 큰 비용일 수 있음

확인합니다.

  • 실행 빈도와 Starts
  • Index Leaf Buffers
  • 후보 ROWID 수
  • Table Buffers
  • 삭제·삽입 패턴
  • Segment 공간과 실제 BLEVEL 변화
  • Rebuild 전후 DML·가용성 비용
CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
BLEVEL 하나
  ≠ Index Rebuild 근거

4. LEAF_BLOCKS와 NUM_ROWS

4.1 LEAF_BLOCKS

LEAF_BLOCKS는 Index Entry가 저장된 Leaf Block 수입니다.

영향을 주는 요소입니다.

  • Index Entry 수
  • Key·포함 Column 폭
  • PCTFREE
  • 삭제·삽입·Block Split
  • Compression
  • Partition 범위

활용합니다.

  • Index Range Scan의 가능한 Leaf 작업량
  • Index Full Scan·Fast Full Scan의 크기
  • Covering Index 확장 비용
  • Data 증가 후 Segment 변화

4.2 NUM_ROWS

일반 B-tree Index의 NUM_ROWS는 Index Entry 수입니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Table NUM_ROWS
  → Table Statistics Row 수

Index NUM_ROWS
  → Index Statistics Entry 수

두 값은 항상 같지 않습니다.

일반 B-tree Index는 모든 Key Column이 NULL인 Row를 저장하지 않는 것이 대표적인 차이 원인입니다.

SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
CREATE INDEX orders_x1
ON orders(optional_code, optional_type);
CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
optional_code IS NULL
AND optional_type IS NULL

→ 일반 B-tree에 Entry가 없을 수 있음

다음 경우에도 차이가 날 수 있습니다.

  • Statistics 수집 시점 차이
  • Partial Index 성격의 Function-Based Index
  • Bitmap Index의 Dictionary 의미 차이
  • Partition·Subpartition 범위 차이

5. DISTINCT_KEYS

DISTINCT_KEYS는 Index 전체 Key 조합의 서로 다른 값 수입니다.

SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
CREATE INDEX orders_x1
ON orders(status, region);
CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
status NDV                    = 4
region NDV                    = 20
실제 (status,region) 조합 NDV = 45

ORDERS_X1.DISTINCT_KEYS       ≈ 45

다음을 구분합니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
선두 Column NDV
  = status만의 Distinct Value 수

DISTINCT_KEYS
  = (status,region) 전체 Index Key 조합의 Distinct 수

Unique·Primary Key Index는 모든 Key가 유일하므로 일반적으로 DISTINCT_KEYS가 Index Row 수와 같은 방향입니다. Nullable Unique Key에서는 All-Key-NULL Entry 제외 등 Object 정의를 함께 확인합니다.


6. Key별 평균 Block Statistics

6.1 AVG_LEAF_BLOCKS_PER_KEY

Distinct Index Key 하나가 평균 몇 개의 Leaf Block에 나타나는지 나타냅니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
값이 1에 가까움
  → 평균적으로 Key Entry가 한 Leaf Block 안에 존재

값이 큼
  → 중복 Key Entry가 여러 Leaf Block에 걸칠 수 있음

Unique·Primary Key Index에서는 공식적으로 항상 1입니다.

6.2 AVG_DATA_BLOCKS_PER_KEY

Distinct Key 하나의 Row가 평균 몇 개의 Table Data Block에 존재하는지 나타냅니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
작음
  → 같은 Key Row가 적은 Table Block에 모임

큼
  → 같은 Key Row가 여러 Table Block에 분산

예시입니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
INDEX STATUS_IX

status='READY' Row
  100,000건
  18,000 Table Blocks 분포

AVG_DATA_BLOCKS_PER_KEY
  → Key별 평균 Table Block 분산을 이해하는 보조값

6.3 평균값의 한계

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
인기 Key 1개
  → 수십만 Row·많은 Block

나머지 Key
  → 소량 Row

평균값
  → 특정 인기 Key의 실제 작업량을 숨길 수 있음

Histogram·Bind 값·실제 A-Rows·Table Buffers를 함께 봅니다.


7. CLUSTERING_FACTOR

Clustering Factor는 B-tree Index Key 순서와 Heap Table Row의 물리 Block 배치 관계를 나타냅니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
CF가 Table BLOCKS에 가까움
  → 같은 Leaf Block의 Index Entry가
    같은·인접 Table Block을 가리키는 경향
  → 넓은 Range Scan에 유리한 방향

CF가 Table NUM_ROWS에 가까움
  → Index 순서의 ROWID가
    여러 Table Block에 무작위로 분산된 방향
  → 많은 후보를 처리할수록 Table Access 증가 가능

CF는 Table 공통값이 아니라 특정 Index의 Statistics입니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
ORDERS_DATE_IX
  → Date 순서와 Table 적재 순서가 유사
  → 낮은 CF 방향

ORDERS_CUSTOMER_IX
  → Customer 순서로 Row가 분산
  → 높은 CF 방향 가능

7.1 CF와 Cost

Optimizer는 CF를 이용해 Index Scan 후 예상 Table Block 방문 Cost를 추정합니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
낮은 CF
  → Index Range Scan이 더 넓은 범위까지 경쟁 가능

높은 CF
  → Full Table Scan이 더 일찍 저렴해질 수 있음

7.2 주의

  • CF는 실제 특정 SQL이 읽을 정확한 Block 수가 아님
  • 후보 Row 수·범위·Cache·BATCHED Access를 함께 봄
  • Covering Index면 Heap Table Access가 없어 CF 영향이 작음
  • 단건·극소수 Probe에서는 높은 CF 영향이 제한적일 수 있음
  • Index Rebuild만으로 Heap Row 배치가 바뀌지 않아 근본 CF는 개선되지 않을 수 있음
  • 한 Index 기준 Table 재배치는 다른 Index CF를 악화시킬 수 있음

8. Partitioned Index Statistics

Partitioned Table·Index에서는 Partition마다 다음이 다를 수 있습니다.

  • BLEVEL
  • LEAF_BLOCKS
  • NUM_ROWS
  • DISTINCT_KEYS
  • AVG_DATA_BLOCKS_PER_KEY
  • CLUSTERING_FACTOR
  • LAST_ANALYZED
CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
최근 Partition
  → 순차 적재·작은 BLEVEL·좋은 CF

과거 Partition
  → Update·재적재·큰 Segment·다른 CF

Query가 Partition Pruning으로 최근 Partition만 읽는데 Global Index Statistics만 보고 판단하면 실제 접근 범위와 어긋날 수 있습니다.

확인합니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Plan PSTART·PSTOP
+ 대상 Index Partition Statistics
+ Global Statistics
+ 실제 A-Rows·Buffers

9. System Statistics의 역할

System Statistics는 Hardware와 Database Workload의 CPU·I/O 특성을 Cost Model에 제공합니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Object Statistics
  → 얼마나 많은 Row·Block을 처리할지

System Statistics
  → 그 작업의 CPU·I/O 상대 비용을 어떻게 환산할지

대표 비교입니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Index 경로
  → 여러 Single Block I/O·CPU Probe

Full Scan 경로
  → Sequential·Multiblock I/O

System Statistics
  → 두 작업의 상대 Cost를 현실에 가깝게 비교

10. Noworkload System Statistics

Oracle Database는 기본적으로 Noworkload Statistics와 CPU Cost Model을 사용할 수 있습니다.

주요 값입니다.

항목의미
CPUSPEEDNWNoworkload 방식의 CPU Speed
IOSEEKTIMI/O Seek Time 특성
IOTFRSPEEDI/O Transfer Speed 특성

수집합니다.

SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
BEGIN
  DBMS_STATS.GATHER_SYSTEM_STATS(
    gathering_mode => 'NOWORKLOAD'
  );
END;
/

수집 방식입니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
실제 업무 Counter 사용 X
Data File에 Random Read 제출
→ CPU·I/O System 특성 측정

주의합니다.

  • I/O System에 추가 부하가 발생
  • Database 크기·Storage에 따라 시간 소요
  • 새 Storage·Tablespace 등 물리 환경 변화 후 검토
  • Oracle은 대부분의 경우 기본값 사용을 권장하며 무조건 수집하지 않음
  • 수집 전에 기존 Statistics Export·복구 절차 준비

11. Workload System Statistics

대표 업무 구간의 실제 활동 Counter로 수집합니다.

주요 값입니다.

항목의미
CPUSPEEDWorkload 기반 CPU Speed
SREADTIM평균 Single Block Read Time
MREADTIM평균 Multiblock Read Time
MBRC평균 Sequential Multiblock Read Count
MAXTHR최대 System I/O Throughput
SLAVETHR평균 Parallel Execution Slave Throughput

수집합니다.

SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
BEGIN
  DBMS_STATS.GATHER_SYSTEM_STATS('START');
END;
/

-- 대표 Workload 수행

BEGIN
  DBMS_STATS.GATHER_SYSTEM_STATS('STOP');
END;
/

또는 INTERVAL을 사용합니다.

11.1 Workload Statistics의 우선순위

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Noworkload와 Workload 모두 존재
  → Optimizer는 Workload Statistics 사용

11.2 대표 구간이 중요한 이유

SREADTIM·MREADTIM·MBRC는 Workload 시작·종료 사이 Buffer Cache의 Physical Sequential·Random Read Counter 등을 이용해 계산됩니다.

따라서 수집 구간의 다음 요소가 반영될 수 있습니다.

  • I/O Latency
  • Latch Contention
  • Task Switching
  • OLTP·Batch·DSS 비율
  • 동시 부하
  • Storage Queue
CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
대표 평상시 Workload
  → 유용한 비용 모델

Backup·장애·비정상 Batch 구간
  → 전체 SQL의 Cost 왜곡 가능

12. MREADTIM·MBRC가 없을 수 있는 경우

OLTP 구간에 Serial Full Scan이 거의 없으면 Workload Statistics 수집 과정에서 MREADTIM이나 MBRC를 얻지 못할 수 있습니다.

Oracle의 처리 방향입니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
MREADTIM·MBRC를 수집·검증하지 못함
+ SREADTIM·CPUSPEED는 존재
→ SREADTIM·CPUSPEED 사용
→ Full Scan Cost에는 DB_FILE_MULTIBLOCK_READ_COUNT 활용 가능

해석합니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Workload Statistics를 수집했다
  ≠ 모든 System Statistics 값이 반드시 채워졌다

SYS.AUX_STATS$에서 실제 값을 확인합니다.

SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
SELECT sname,
       pname,
       pval1,
       pval2
FROM   sys.aux_stats$
WHERE  sname IN ('SYSSTATS_INFO','SYSSTATS_MAIN')
ORDER  BY sname, pname;

권한과 내부 Table 접근 정책을 확인합니다.


13. Index·Full Scan Cost 연결

개념적인 Index 경로입니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Index Cost
  ≈ BLEVEL 수직 탐색
   + 예상 Leaf Block Scan
   + 예상 Table Block 방문
   + CPU Predicate·Join·Sort

개념적인 Full Scan 경로입니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Full Scan Cost
  ≈ 대상 Table Blocks
   + Multiblock I/O 특성
   + CPU Predicate·Join·Sort
   + Parallel Overhead

주요 연결입니다.

통계Cost에 미치는 대표 영향
BLEVELProbe 수직 탐색
LEAF_BLOCKSRange·Full Index Scan 크기
DISTINCT_KEYSKey 중복도·등치 평균
AVG_LEAF_BLOCKS_PER_KEY동일 Key Leaf 범위
AVG_DATA_BLOCKS_PER_KEY동일 Key Table Block 분산
CLUSTERING_FACTORRange Scan Table Access Cost
SREADTIMSingle Block I/O 상대 Cost
MREADTIM·MBRCMultiblock·Full Scan 상대 Cost
CPUSPEEDPredicate·Join·Sort CPU Cost

실제 Oracle Cost 공식은 이보다 복잡하므로 개념 모델을 절대 산식으로 사용하지 않습니다.


14. System Statistics와 Cursor 재사용

Oracle 공식 설명에 따르면 System Statistics 갱신은 이전에 Parse된 SQL을 무효화하지 않습니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
기존 Shared Cursor
  → 기존 Plan을 계속 재사용할 수 있음

새 SQL·새 Hard Parse
  → 갱신된 System Statistics로 Cost 계산

따라서 변경 검증은 다음을 확인합니다.

  • 기존 Child Cursor인지
  • 새로운 Child Number인지
  • Plan Hash Value가 바뀌었는지
  • Hard Parse 시점이 Statistics 변경 이후인지
  • Bind·Optimizer Parameter가 동일한지

특정 SQL 하나를 고치기 위해 System Statistics를 변경하면 이후 Hard Parse되는 많은 SQL의 Cost에 영향을 줄 수 있습니다.


15. 수집·복구 운영

15.1 Export

SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
BEGIN
  DBMS_STATS.CREATE_STAT_TABLE(
    ownname => USER,
    stattab => 'SYSTEM_STATS_BAK'
  );

  DBMS_STATS.EXPORT_SYSTEM_STATS(
    stattab => 'SYSTEM_STATS_BAK',
    statid  => 'BEFORE_CHANGE'
  );
END;
/

15.2 삭제·기본 복귀

SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
BEGIN
  DBMS_STATS.DELETE_SYSTEM_STATS;
END;
/

Workload Statistics가 Dictionary에 있으면 삭제 후 Noworkload 기본 방향으로 돌아갑니다.

15.3 검증 원칙

  • 대표 Workload 구간 정의
  • 변경 전 Export
  • Test·Canary 환경 검증
  • 새 Hard Parse된 대표 SQL 비교
  • OLTP·Batch·DW SQL 모두 확인
  • Plan Regression·Hard Parse 부하 확인
  • Rollback 절차 준비

16. 실행계획과 Runtime 검증

SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
SELECT /*+ GATHER_PLAN_STATISTICS */
       order_id,
       amount
FROM   orders
WHERE  status=:status
AND    order_date>=:from_dt
AND    order_date< :to_dt;
SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
SELECT *
FROM TABLE(
  DBMS_XPLAN.DISPLAY_CURSOR(
    :sql_id,
    :child_no,
    'ALLSTATS LAST +PREDICATE +NOTE'
  )
);

Index 경로에서 확인합니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Index Starts·E-Rows·A-Rows·Buffers·Reads
Table A-Rows·Buffers·Reads
Access·Index Filter·Table Filter
후보 ROWID와 최종 Row 차이

Full Scan 경로에서 확인합니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Table Blocks·Buffers·Reads
Parallel·Direct Path 여부
Predicate CPU
Sort·TEMP

System Statistics 변경 전후에는 다음을 같이 기록합니다.

  • Child Number·Plan Hash
  • Cost
  • Buffers·Reads
  • CPU·Elapsed·P95
  • Parse Calls·Hard Parse
  • 첫 행·전체 Fetch
  • 동시 Workload 영향

17. 자주 혼동하는 판단

혼동정확한 기준
BLEVEL=1이면 Root와 Leaf가 같은 Block이다Root와 Leaf가 같으면 BLEVEL=0이다
BLEVEL 증가면 즉시 Rebuild실제 Probe·Leaf·Table Cost와 운영비를 본다
DISTINCT_KEYS는 선두 Column NDV다전체 Index Key 조합의 NDV다
Unique Index의 Key별 Leaf 평균은 값마다 다르다AVG_LEAF_BLOCKS_PER_KEY는 공식적으로 1이다
Table NUM_ROWS와 Index NUM_ROWS는 항상 같다All-Key-NULL Entry 제외·시점·Index 유형을 본다
높은 CF는 Index Leaf 정렬 불량이다Index 순서와 Heap Table Block 배치 관계다
Workload Statistics를 모으면 모든 항목이 채워진다OLTP 구간에는 MREADTIM·MBRC가 없을 수 있다
Workload와 Noworkload가 함께 있으면 평균낸다Workload Statistics가 우선 사용된다
System Statistics 변경 즉시 기존 Plan이 바뀐다기존 Cursor는 무효화되지 않고 새 Parse부터 반영된다
Cost가 낮으면 실제 시간도 반드시 낮다실제 Buffers·Wait·Elapsed·동시성으로 검증한다

스스로 확인하기

개념 확인 문제

문제를 누르면 바로 아래에서 정답과 해설을 확인할 수 있습니다.

01Index 경로의 비용 단계를 Root 탐색부터 Table Access까지 설명하시오.
정답 및 해설

Index 경로 단계

  • Root·Branch 수직 탐색
  • 시작 Leaf Block 도달
  • 조건 범위의 Leaf Entry Scan
  • 후보 ROWID 반환
  • Heap Table Block 접근
  • Table Filter·Projection·Join 처리 순서입니다.
02BLEVEL=0, BLEVEL=1의 구조 차이를 설명하시오.
정답 및 해설

BLEVEL

  • BLEVEL=0은 Root Block과 Leaf Block이 같은 구조입니다.
  • BLEVEL=1은 Root 아래 Leaf Level이 존재합니다.
  • 값은 Root에서 Leaf까지의 B-tree Level을 나타냅니다.
03LEAFBLOCKS와 Index NUMROWS가 나타내는 값을 설명하시오.
정답 및 해설

Leaf·Entry 규모

  • LEAF_BLOCKS는 Index Entry가 저장된 Leaf Block 수입니다.
  • Index NUM_ROWS는 Index Entry 수입니다.
  • 일반 B-tree에서 모든 Key가 NULL인 Row는 Entry가 없어 Table NUM_ROWS와 다를 수 있습니다.
04복합 Index의 DISTINCTKEYS와 선두 Column NDV의 차이를 설명하시오.
정답 및 해설

DISTINCT_KEYS

  • 복합 Index에 정의된 모든 Key Column 조합의 Distinct 수입니다.
  • 선두 Column 하나의 NDV와 같지 않으며 Column 상관관계 때문에 개별 NDV 곱과도 다를 수 있습니다.
05AVGLEAFBLOCKSPERKEY와 AVGDATABLOCKSPERKEY를 비교하시오.
정답 및 해설

Key별 평균값

  • AVG_LEAF_BLOCKS_PER_KEY는 Distinct Key Entry가 평균 몇 Leaf Block에 걸치는지 나타냅니다.
  • AVG_DATA_BLOCKS_PER_KEY는 같은 Key의 Table Row가 평균 몇 Data Block에 분포하는지 나타냅니다.
  • 둘 다 평균이므로 인기값의 실제 작업량은 Runtime으로 확인합니다.
06Clustering Factor가 Index Range Scan과 Full Scan Cost 비교에 미치는 영향을 설명하시오.
정답 및 해설

Clustering Factor

  • Table Blocks에 가까운 CF는 Index 순서의 ROWID가 같은·인접 Block을 가리키는 방향입니다.
  • Table Rows에 가까우면 Row가 여러 Block에 흩어진 방향입니다.
  • 높은 CF에서는 후보 Row가 많을수록 Full Scan이 더 일찍 유리할 수 있습니다.
07Noworkload와 Workload System Statistics의 수집 방식·항목·우선순위를 설명하시오.
정답 및 해설

Noworkload·Workload

  • Noworkload는 Random Data File Read 등으로 CPUSPEEDNW·IOSEEKTIM·IOTFRSPEED를 측정합니다.
  • Workload는 대표 업무 구간 Counter로 CPUSPEED·SREADTIM·MREADTIM·MBRC·MAXTHR·SLAVETHR를 수집합니다.
  • 두 통계가 있으면 Workload Statistics가 우선합니다.
08OLTP Workload Statistics에서 MREADTIM·MBRC가 비어 있을 수 있는 이유를 설명하시오.
정답 및 해설

MREADTIM·MBRC 부재

  • OLTP 구간에 Serial Table Scan이 거의 없으면 Multiblock Read Sample이 충분하지 않을 수 있습니다.
  • SREADTIM·CPUSPEED만 사용하고 Full Scan Cost에 DB_FILE_MULTIBLOCK_READ_COUNT를 활용할 수 있습니다.
09System Statistics 변경 후 기존 Cursor와 새 Hard Parse의 차이를 설명하시오.
정답 및 해설

Cursor 차이

  • System Statistics 갱신은 이미 Parse된 SQL을 무효화하지 않습니다.
  • 기존 Child Cursor는 이전 Plan을 계속 재사용할 수 있습니다.
  • 새 SQL 또는 새 Hard Parse부터 변경된 Statistics로 Cost를 계산합니다.
10Index·System Statistics 개선을 실제 Runtime과 안전하게 검증하는 절차를 설명하시오.
정답 및 해설

검증 절차 - 변경 전 Index·System Statistics와 대표 SQL Child·Plan·Runtime을 저장합니다. - System Statistics를 Export하고 대표 구간에서 제한적으로 수집합니다. - 새 Hard Parse된 동일 Bind SQL의 E/A·Cost·Plan을 확인합니다. - Buffers·Reads·CPU·Elapsed·P95와 OLTP·Batch·DW 회귀를 비교합니다. - 문제 발생 시 Export Statistics 또는 기본 Statistics로 복구합니다.