현재 선택한 SQL 과정

SQLP 이론 학습

이론 목록으로 돌아가기

옵티마이저 통계의 기초: Table·Column Statistics 읽기

NUM_ROWS·BLOCKS와 NDV·NULL·Low/High·Histogram이 기본 Cardinality와 값별 Selectivity 추정에 미치는 영향을 이해합니다.

예상 읽기 23

핵심 요약

Oracle Optimizer는 SQL을 실행하기 전에 모든 Data를 직접 읽을 수 없으므로 Data Dictionary의 Optimizer Statistics로 각 후보 Plan의 Selectivity·Cardinality·Cost를 추정합니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Table·Column·Index·System Statistics
+ Extended·Dynamic Statistics
→ Predicate Selectivity
→ Row Source Cardinality
→ Access Path·Join Order·Join Method·Sort 비용
→ 최저 Cost Plan 선택

Optimizer Statistics는 실시간 계측값이 아니라 수집·유지 시점의 Data를 요약한 값입니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Optimizer Statistics
  → 실행 전 예상
  → E-Rows·Cost의 근거

Runtime Statistics
  → 특정 Cursor 실행의 실제 작업량
  → Starts·A-Rows·Buffers·Reads·A-Time

통계 진단의 핵심은 숫자를 단독으로 보는 것이 아니라 다음 흐름을 연결하는 것입니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
통계 값·수집 범위·시점
→ Optimizer 예상 E-Rows
→ 선택된 Access Path·Join
→ 실제 A-Rows·Buffers
→ 최초 추정 오차 원인

이 이론의 범위

이 이론은 SQLP의 SQL 고급활용 및 튜닝 → 옵티마이저와 통계정보 → Table·Column Statistics 범위에서 기본 통계의 의미와 실행계획 추정 오류 진단을 다룹니다.


학습 목표

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

  • Optimizer Statistics와 Runtime Statistics를 구분한다.
  • NUM_ROWS, BLOCKS, AVG_ROW_LEN, SAMPLE_SIZE를 해석한다.
  • NUM_DISTINCT, NUM_NULLS, LOW_VALUE, HIGH_VALUE, DENSITY를 해석한다.
  • Histogram이 없는 등치 Predicate의 단순 Selectivity·Cardinality 모델을 설명한다.
  • Non-NULL 평균 빈도와 Optimizer의 단순 공식을 구분한다.
  • Histogram 유형과 DENSITY의 한계를 설명한다.
  • LAST_ANALYZED, STALE_STATS, STALE_PERCENT를 함께 해석한다.
  • Global·Partition Statistics와 Incremental Statistics의 관계를 설명한다.
  • Extended Statistics와 Dynamic Statistics가 필요한 조건을 설명한다.
  • Starts가 있는 Row Source에서 E-Rows·A-Rows 비교 단위를 맞춘다.
  • 최초 Cardinality 오차 지점에서 필요한 통계만 선택해 보완한다.

1. Optimizer Statistics의 역할

Optimizer의 Estimator는 Data Dictionary Statistics를 사용해 다음을 예상합니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Selectivity
  → Predicate가 전체 Row 중 선택할 비율

Cardinality
  → 각 Plan Operation이 반환할 예상 Row 수

Cost
  → 예상 I/O·CPU·Memory 사용량의 내부 비교값

Cardinality는 Access Path·Join Order·Join Method·Sort Memory에 연쇄적으로 영향을 줍니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Driving Row 과대 추정
  → Hash Join·Full Scan 쪽 비용이 상대적으로 유리해질 수 있음

Driving Row 과소 추정
  → Nested Loops Inner Probe가 실제로 과도하게 반복될 수 있음

Cost는 실행 초 단위가 아니며 동일 SQL·동일 Optimizer 환경의 후보 Plan을 비교하는 내부 숫자입니다.


2. Statistics 종류

종류대표 정보주요 용도
Table StatisticsRow·Block·평균 Row 길이Full Scan·Join 입력 크기
Column StatisticsNDV·NULL·Low/High·HistogramPredicate Selectivity·Cardinality
Index StatisticsBLEVEL·Leaf Blocks·ClusteringIndex Scan·ROWID Access Cost
System StatisticsCPU·Single/Multiblock I/OI/O·CPU 작업의 공통 Cost 비교
Extended StatisticsColumn Group·Expression상관 Column·표현식 Predicate
Dynamic StatisticsParse 중 Block Sample통계 Missing·Stale·Insufficient 보완
Runtime StatisticsStarts·A-Rows·Buffers 등실행 후 예상 오차·실제 병목 확인

이 이론은 Table·Column Statistics를 중심으로 하며, 다른 종류는 원인을 분류하는 수준에서 연결합니다.


3. Optimizer Statistics와 Runtime Statistics

구분Optimizer StatisticsRuntime Statistics
시점Parse·Optimization 전 사용SQL 실행 중·후 측정
목적예상 Plan 선택실제 작업량 검증
대표 ViewUSER_TAB_STATISTICS, USER_TAB_COL_STATISTICSV$SQL_PLAN_STATISTICS_ALL, Cursor
대표 값NUM_ROWS, NDV, HistogramStarts, A-Rows, Buffers, Reads
Plan 표시E-Rows, CostALLSTATS LAST의 A-Rows 등
범위Object의 수집 시점 요약특정 SQL_ID·Child Cursor·실행
CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
NUM_ROWS=1,000,000
  ≠ 지금 이 순간 COUNT(*)=1,000,000이라는 보장

A-Rows=15,000
  = 해당 Cursor 실행에서 Row Source가 상위로 반환한 실제 Row

4. Table Statistics

4.1 주요 항목

항목의미해석
NUM_ROWSObject Statistics의 Row 수Cardinality·Join 입력의 기준
BLOCKSStatistics에 기록된 사용 Data Block 수Full Scan Cost의 핵심 입력
AVG_ROW_LENRow Overhead를 포함한 평균 Row 길이Bytes·Memory·I/O 예상
SAMPLE_SIZE통계 수집에 사용된 Sample Row 수수집 근거와 규모 확인
LAST_ANALYZED최근 Statistics 수집 시각현재 Data와 시점 차이 확인
STALE_STATS변경량 기준 Stale 여부자동·수동 재수집 후보
GLOBAL_STATSGather·Incremental 유지 여부Partition·Global 범위 해석
USER_STATS사용자가 Statistics를 직접 설정했는지인위적 통계 여부 확인
NOTESOnline·Incremental 등 추가 속성Statistics 생성 경로 확인
SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
SELECT table_name,
       partition_name,
       object_type,
       num_rows,
       blocks,
       avg_row_len,
       sample_size,
       last_analyzed,
       stale_stats,
       global_stats,
       user_stats,
       notes
FROM   user_tab_statistics
WHERE  table_name = 'ORDERS'
ORDER  BY object_type, partition_name;

4.2 BLOCKS와 Segment 할당량

USER_TAB_STATISTICS.BLOCKS는 Optimizer Statistics의 Used Block 수입니다. Segment에 할당된 전체 Block·Byte는 별도 View에서 확인합니다.

SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
SELECT segment_name,
       segment_type,
       blocks,
       bytes
FROM   user_segments
WHERE  segment_name = 'ORDERS';
CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Table Statistics BLOCKS
  → Cost 계산용 Object 통계

Segment BLOCKS
  → 현재 할당된 물리 공간

High Water Mark Scan 범위
  → 실제 Full Scan·Segment 상태와 연결해 별도 확인

같은 이름의 Column을 혼합하지 않습니다.


5. Statistics 수집 Sample

DBMS_STATS.GATHER_TABLE_STATSESTIMATE_PERCENT는 Sample 비율을 제어합니다. 기본 방향은 DBMS_STATS.AUTO_SAMPLE_SIZE로 Oracle이 적절한 Sample을 선택하게 하는 것입니다.

SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
BEGIN
  DBMS_STATS.GATHER_TABLE_STATS(
    ownname          => USER,
    tabname          => 'ORDERS',
    estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE,
    method_opt       => 'FOR ALL COLUMNS SIZE AUTO',
    cascade          => DBMS_STATS.AUTO_CASCADE
  );
END;
/

확인할 사항입니다.

  • SAMPLE_SIZE가 작다고 Statistics가 반드시 나쁜 것은 아님
  • 100% Sample이 모든 상관관계·표현식 문제를 자동 해결하지 않음
  • Column Group·Expression Statistics가 없으면 Data 관계를 표현하지 못할 수 있음
  • Partitioned Table은 GRANULARITY, Incremental 설정과 Global Statistics를 함께 확인
  • CASCADE는 Index Statistics 수집 여부와 연결됨
CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Sample 정확도
  + 필요한 Statistics 종류
  + Data 분포·상관관계 표현
  → 전체 통계 품질

6. Column Statistics

6.1 주요 항목

항목의미주의
NUM_DISTINCTNon-NULL Distinct Value 수, NDVNULL은 별도 관리
NUM_NULLSNULL Row 수Equality 결과에는 일반적으로 포함되지 않음
LOW_VALUE통계상 최솟값RAW 내부 형식
HIGH_VALUE통계상 최댓값증가형 Column의 최신 범위 확인
DENSITY값 Selectivity 계산에 쓰이는 밀도Histogram 유무에 따라 의미가 달라짐
AVG_COL_LEN평균 Column Byte 길이Row·Projection Bytes 예상
HISTOGRAMHistogram 유형편중 표현 방식
NUM_BUCKETSHistogram Bucket 수Histogram 유형과 함께 해석
SAMPLE_SIZEColumn Statistics Sample Row 수Table Sample과 비교
LAST_ANALYZEDColumn 최근 분석 시각Table Statistics 시점과 비교
SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
SELECT column_name,
       num_distinct,
       num_nulls,
       low_value,
       high_value,
       density,
       avg_col_len,
       histogram,
       num_buckets,
       sample_size,
       last_analyzed,
       global_stats,
       notes
FROM   user_tab_col_statistics
WHERE  table_name = 'ORDERS'
ORDER  BY column_name;

6.2 Histogram 유형

Oracle 26ai Data Dictionary가 표시할 수 있는 대표 유형입니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
NONE
FREQUENCY
TOP-FREQUENCY
HYBRID
HEIGHT BALANCED

Histogram은 별도 이론에서 자세히 다루지만 기본 원칙은 다음과 같습니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Histogram 없음
  → 균등 분포 가정의 영향이 큼

Histogram 있음
  → 인기값·비인기값·Bucket 정보로 값별 추정 보완

7. 단순 등치 조건 추정

7.1 Oracle의 가장 단순한 공식

단일 Table·단일 Equality Predicate·Histogram 없음이라는 단순 조건에서 Oracle 문서는 다음 모델을 설명합니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Selectivity ≈ 1 / NDV
Cardinality ≈ NUM_ROWS / NDV

예시입니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
NUM_ROWS = 1,000,000
NDV      = 4

개념적 Cardinality ≈ 250,000

실제 Optimizer에는 NULL·Density·Bind·Data Type·Histogram·Internal 보정이 추가될 수 있습니다.

7.2 Non-NULL 평균 빈도

Data 자체의 평균 빈도를 이해할 때는 다음 계산도 유용합니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Non-NULL Row = NUM_ROWS - NUM_NULLS
Average Non-NULL Frequency
  = (NUM_ROWS - NUM_NULLS) / NDV

예시입니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
NUM_ROWS  = 1,000,000
NUM_NULLS =   100,000
NDV       =         4

Non-NULL 평균 빈도 = 900,000 / 4 = 225,000

두 계산을 혼동하지 않습니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
NUM_ROWS / NDV
  → Oracle 문서의 가장 단순한 Cardinality 설명

(ROWS - NULLS) / NDV
  → Data의 Non-NULL 값당 평균 빈도 이해

실제 E-Rows
  → Density·Histogram·Predicate·Optimizer 계산 결과

8. DENSITY를 해석하는 방법

Oracle Data Dictionary의 공식 설명입니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Histogram 없음
  DENSITY = 1 / NUM_DISTINCT

Histogram 있음
  DENSITY는 Histogram Endpoint 관계를 반영
  모든 값의 Selectivity를 단일 DENSITY로 설명할 수 없음

따라서 다음 판단은 위험합니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
DENSITY 하나
→ 모든 Popular·Nonpopular 값 Cardinality를 동일하게 계산

값 편중이 있는 경우 Histogram Bucket·Endpoint와 실제 Bind 값을 함께 봅니다.


9. NULL Statistics와 Predicate

9.1 Equality

SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
WHERE status = 'READY'

NULL은 Equality TRUE가 아니므로 일반 결과에 포함되지 않습니다.

9.2 IS NULL

SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
WHERE status IS NULL

NUM_NULLS가 직접 관련된 Predicate입니다.

9.3 NOT IN

NULL 포함 여부는 3값 논리 때문에 결과 의미를 크게 바꿀 수 있으며 단순 NDV 추정 문제와 구분합니다.

9.4 Join

Nullable Join Column은 NULL Row가 Equality Join에 매칭되지 않는다는 점을 Cardinality에서 고려해야 합니다.


10. LOW_VALUE·HIGH_VALUE

LOW_VALUEHIGH_VALUE는 Column의 통계상 최솟값·최댓값이며 RAW로 저장됩니다.

중요한 상황입니다.

  • 날짜·Sequence가 계속 증가
  • Statistics 이후 최신 값이 HIGH_VALUE 밖으로 증가
  • 과거 Data 삭제 후 실제 범위가 축소
  • Range Predicate가 통계 범위 밖을 조회
  • Partition별 Low·High와 Global 범위가 다름
CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Statistics HIGH_VALUE = 2026-07-01
실제 Data Max         = 2026-08-01
Predicate             = 2026-07-31 이상

→ 최신 구간 빈도·Cardinality를 부정확하게 추정할 수 있음

LOW_VALUE·HIGH_VALUE는 전체 분포를 보여 주는 Histogram이 아니며 단순 문자열 변환 결과만으로 분포를 단정하지 않습니다.


11. STALE_STATS와 STALE_PERCENT

Oracle은 Table Monitoring의 근사 DML 변경량과 DBMS_STATSSTALE_PERCENT Preference를 사용해 Stale 여부를 판단합니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
STALE_STATS = YES
  → 변경량 기준으로 Statistics가 Stale

STALE_STATS = NO
  → Stale 임계치를 넘지 않음

STALE_STATS = NULL
  → Statistics가 수집되지 않은 상태 가능
SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
SELECT DBMS_STATS.GET_PREFS(
         pname   => 'STALE_PERCENT',
         ownname => USER,
         tabname => 'ORDERS'
       ) AS stale_percent
FROM dual;

STALE_STATS='NO'가 보장하지 않는 것:

  • 특정 인기값에 변경이 집중되지 않았음
  • Column 상관관계가 정확함
  • Expression Statistics가 충분함
  • 최신 증가형 값이 HIGH_VALUE 안에 있음
  • 특정 Partition과 Global Statistics가 모두 적절함
  • 모든 Bind의 Cardinality가 정확함

11.1 오래돼도 영향이 작은 경우

  • 거의 변하지 않는 Code Table
  • 항상 PK 단건 조회
  • Data 변화가 Plan 선택에 민감하지 않음

11.2 짧은 시간에도 문제인 경우

  • 대량 Load·Partition Exchange 직후
  • 특정 Status·Tenant에 Data가 집중
  • 최신 날짜만 급증
  • Column 관계가 업무 변화로 변경
  • Statistics 없는 신규 Partition

12. Global·Partition Statistics

Partitioned Table은 다음 수준의 Statistics를 가질 수 있습니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Global Table Statistics
Partition Statistics
Subpartition Statistics
Global·Partition Column Statistics

Query가 Partition Pruning으로 한 Partition만 읽는다면 대상 Partition Statistics가 중요합니다. 여러 Partition을 조회하면 Global Statistics와 Partition Statistics의 일관성을 확인합니다.

Incremental Statistics는 Partition Synopsis를 이용해 Global Statistics 유지 비용을 줄이는 데 도움을 줄 수 있습니다.

확인합니다.

  • PARTITION_NAME, OBJECT_TYPE
  • GLOBAL_STATS, NOTES
  • Partition NUM_ROWS·BLOCKS
  • Global·Partition LAST_ANALYZED
  • 신규·교환 Partition의 통계
  • Pruning된 Plan의 PSTART·PSTOP

13. Extended·Dynamic Statistics

13.1 Column Group Statistics

SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
WHERE region_code = :region
AND   store_code  = :store

두 Column이 강하게 상관되면 개별 NDV를 독립적으로 곱하는 추정이 크게 틀릴 수 있습니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Column Group Statistics
  → 같은 Table의 여러 Column 관계를 표현

13.2 Expression Statistics

SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
WHERE UPPER(customer_name) = :name

Base Column Statistics만으로 Expression 결과 분포를 알기 어렵습니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Expression Statistics
  → 함수·계산식 결과의 Selectivity 추정 보완

13.3 Dynamic Statistics

Optimizer Statistics가 Missing·Stale·Insufficient하거나 Parallel Query 등의 조건에서 Parse 중 Table Block Sample을 읽어 보조 추정을 만들 수 있습니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
장점
  → 부족한 Statistics를 Parse 시점에 일부 보완

비용
  → Recursive SQL·Hard Parse Overhead
  → 영구 Statistics를 완전히 대체하지 않음

14. 실행계획에서 추정 오류 찾기

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

예시입니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
| Id | Operation          | Starts | E-Rows | A-Rows | Buffers |
|---:|--------------------|-------:|-------:|-------:|--------:|
|  1 | TABLE ACCESS FULL  |      1 | 250000 |  15000 |   12000 |
CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
E-Rows
  → Optimizer 예상

A-Rows
  → 실제 상위 반환 Row

Buffers
  → 실제 Logical Block 작업량

14.1 아래 Row Source부터 본다

최종 SELECT Operation만 보지 않고 Plan Tree 아래에서 처음 E-Rows와 A-Rows가 크게 갈라지는 지점을 찾습니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
최초 오차 지점
→ 해당 Table·Predicate·Join의 통계를 점검

14.2 Starts가 있는 경우

E-Rows는 Operation의 한 번 Start당 예상 Row로 해석되는 경우가 많고, A-Rows는 화면에서 여러 Starts의 총 Output으로 표시될 수 있습니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Starts = 1
  → E-Rows와 A-Rows 직접 비교 가능

Starts = 10,000
  → Actual per Start ≈ A-Rows / Starts
  → 또는 Expected Total ≈ E-Rows × Starts

반복 Nested Loops·Subquery에서는 비교 단위를 맞추지 않으면 추정 오차를 잘못 판단할 수 있습니다.

14.3 Buffers 합산 주의

상위 Row Source의 Runtime Statistics는 하위 작업을 포함할 수 있습니다. 모든 Plan Line의 Buffers를 단순 합산하지 않습니다.


15. 원인별 개선 선택

최초 오차 원인확인후보 개선
Row·Block 규모 변화NUM_ROWS, BLOCKS, DMLTable Statistics 재수집
값 편중Histogram·Bind 분포필요한 Column Histogram
Column 상관관계복합 PredicateColumn Group Statistics
함수·표현식Expression PredicateExpression Statistics·FBI
범위 밖 최신값Low/High·Data MaxStatistics Refresh·Partition 전략
Statistics 없음·부족Notes·Dynamic Sampling영구 Statistics 또는 Dynamic 설정
Partition 불일치Global·Partition StatsGranularity·Incremental 운영
SQL 의미·Data TypePredicate·BindSQL·Bind Type 개선

통계를 무조건 전체 재수집하는 대신 필요한 범위를 선택합니다.


16. 적용 판단 절차

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
1. SQL_ID·Child Cursor·실제 Bind·Optimizer 환경을 확정한다.
2. Plan Tree 아래에서 최초 E-Rows·A-Rows 오차 지점을 찾는다.
3. Starts를 반영해 예상·실제 비교 단위를 맞춘다.
4. Table NUM_ROWS·BLOCKS·Sample·LAST_ANALYZED를 확인한다.
5. Predicate Column의 NDV·NULL·Density·Histogram·Low/High를 확인한다.
6. Stale Percent·DML 변화·Partition 범위를 확인한다.
7. 편중·상관·Expression·Missing Statistics로 원인을 분류한다.
8. 필요한 Statistics만 Gather·Extended·Dynamic 방식으로 보완한다.
9. 동일 Bind·Fetch에서 Plan·A-Rows·Buffers·Reads·Elapsed를 재검증한다.
10. Plan 변화·Cursor Invalidations·다른 SQL 회귀를 Monitoring한다.

자주 혼동하는 판단

혼동정확한 기준
NUM_ROWS는 현재 COUNT(*)다Statistics 수집·유지 시점의 Object Row 통계다
BLOCKS는 Segment 할당 Block이다Optimizer Statistics의 Used Block이며 Segment View와 구분한다
SAMPLE_SIZE가 작으면 무조건 나쁘다AUTO_SAMPLE_SIZE·Algorithm과 필요한 Statistics 종류를 함께 본다
DENSITY는 항상 1/NDV다Histogram이 없을 때 그렇고 Histogram이 있으면 의미가 달라진다
Equality Cardinality는 항상 (Rows-Nulls)/NDVOracle의 가장 단순 공식은 Rows/NDV이며 실제 계산은 더 복잡하다
LOW/HIGH가 분포를 모두 설명한다통계상 범위이며 Histogram과 다르다
STALE_STATS=NO면 정확하다변경률 임계치만 통과했으며 편중·상관·범위 밖 문제는 남는다
100% Sample이면 모든 추정이 정확하다상관·표현식·Bind·SQL 구조 문제는 별도다
E-Rows≠A-Rows이면 전체 통계를 재수집한다최초 오차 원인에 맞는 통계를 선택한다
Starts가 커도 E-Rows와 A-Rows를 그대로 비교한다Per-Start 또는 Total 기준을 맞춘다

스스로 확인하기

개념 확인 문제

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

01Optimizer Statistics와 Runtime Statistics의 목적 차이를 설명하시오.
정답 및 해설

두 통계의 차이

  • Optimizer Statistics는 실행 전에 Selectivity·Cardinality·Cost를 추정해 Plan을 선택하기 위한 Object 요약값입니다.
  • Runtime Statistics는 특정 Cursor 실행의 Starts·A-Rows·Buffers·Reads·시간을 측정한 값입니다.
02NUMROWS, BLOCKS, AVGROWLEN, SAMPLESIZE를 설명하시오.
정답 및 해설

Table Statistics

  • NUM_ROWS는 Object의 Statistics Row 수입니다.
  • BLOCKS는 Statistics에 기록된 사용 Data Block 수입니다.
  • AVG_ROW_LEN은 Row Overhead를 포함한 평균 Row Byte 길이입니다.
  • SAMPLE_SIZE는 Statistics 수집에 사용된 Sample Row 수입니다.
03NUMDISTINCT, NUMNULLS, LOWVALUE, HIGHVALUE, DENSITY를 설명하시오.
정답 및 해설

Column Statistics

  • NUM_DISTINCT는 Non-NULL Distinct Value 수입니다.
  • NUM_NULLS는 NULL Row 수입니다.
  • LOW_VALUE·HIGH_VALUE는 RAW 형식의 통계상 최솟값·최댓값입니다.
  • DENSITY는 값 Selectivity 계산에 사용되며 Histogram 유무에 따라 의미가 다릅니다.
04Histogram이 없는 단순 Equality에서 Oracle의 공식과 Non-NULL 평균 빈도를 구분하시오.
정답 및 해설

단순 공식 구분

  • Oracle 문서의 가장 단순한 Equality 모델은 Selectivity=1/NDV, Cardinality=NUM_ROWS/NDV입니다.
  • Data의 Non-NULL 값당 평균 빈도는 (NUM_ROWS-NUM_NULLS)/NDV입니다.
  • 실제 E-Rows는 Density·Histogram·Predicate·내부 보정을 반영할 수 있습니다.
05Histogram 유무에 따라 DENSITY의 의미가 달라지는 이유를 설명하시오.
정답 및 해설

DENSITY

  • Histogram이 없으면 DENSITY는 1/NUM_DISTINCT입니다.
  • Histogram이 있으면 Endpoint 관계를 반영하므로 모든 값의 Selectivity를 단일 Density로 계산할 수 없습니다.
  • 실제 Bind가 인기값인지 비인기값인지 확인합니다.
06STALESTATS, STALEPERCENT, LASTANALYZED를 함께 봐야 하는 이유를 설명하시오.
정답 및 해설

Stale 해석

  • LAST_ANALYZED는 수집 시각입니다.
  • STALE_STATS는 Monitoring 변경량과 STALE_PERCENT 임계치에 기반합니다.
  • NO라도 특정 값 편중·상관관계·High Value 밖 신규 Data 문제는 남을 수 있습니다.
07Global·Partition Statistics가 불일치할 때 발생할 수 있는 문제를 설명하시오.
정답 및 해설

Partition Statistics

  • Pruned Query는 대상 Partition Row·Block 분포가 중요합니다.
  • 여러 Partition Query는 Global Statistics가 전체 Cardinality를 적절히 표현해야 합니다.
  • 신규·교환 Partition과 오래된 Global Statistics가 섞이면 Join·Access Path 추정이 틀릴 수 있습니다.
08Column Group·Expression·Dynamic Statistics의 적용 조건을 설명하시오.
정답 및 해설

보조 Statistics

  • Column Group은 같은 Table의 상관 Column Predicate를 보완합니다.
  • Expression Statistics는 함수·계산식 Predicate 분포를 보완합니다.
  • Dynamic Statistics는 Missing·Stale·Insufficient Statistics를 Parse 중 Sample로 일부 보완합니다.
09Starts가 있는 Plan에서 E-Rows·A-Rows를 올바르게 비교하는 방법을 설명하시오.
정답 및 해설

Starts 비교

  • Starts=1이면 E-Rows와 A-Rows를 직접 비교할 수 있습니다.
  • Starts가 크면 Actual per Start를 A-Rows/Starts로 보거나 Expected Total을 E-Rows×Starts로 계산해 단위를 맞춥니다.
  • Nested Loops 반복을 고려하지 않으면 추정 오차를 잘못 판단할 수 있습니다.
10최초 Cardinality 오차 지점에서 원인에 맞는 Statistics를 선택하는 절차를 설명하시오.
정답 및 해설

진단 절차 - Plan 아래에서 최초 E/A 오차 Operation을 찾습니다. - Table·Column·Partition Statistics와 실제 Bind를 확인합니다. - 원인을 규모 변화·편중·상관·표현식·범위 밖 값·Missing Statistics로 분류합니다. - 필요한 Statistics만 수집·확장한 뒤 동일 조건에서 Plan·Runtime과 다른 SQL 회귀를 재검증합니다.