본문 바로가기
DB/sql

[Oracle] 통계정보(Statistics)

by 혀끄니 2025. 12. 25.
728x90
  • 통계정보란?

- 옵티마이저가 실행계획을 세울때 참고하는 데이터에 대한 정량적 정보(메타데이터)

  • 주요 구성요소

1. Row Count (행 수)

- 테이블 전체 행(row) 수. 옵티마이저가 쿼리의 기본 규모를 판단하는 가장 기초적 통계.

- 조인 방식(Nested Loop vs Hash/Sort-Merge) 결정 시 기준이 됨.

- 인덱스 사용 여부 판단의 기반(작은 테이블이면 인덱스 오버헤드 때문에 풀스캔이 낫다).

- 전체 예상 결과 행수(카디널리티) 계산의 시작값.

ex)

- 테이블 A: 100행 → 인덱스 검색 오버헤드가 상대적으로 크므로 풀스캔이 더 빠를 수 있음.

- 테이블 A: 10,000,000행 → 인덱스/파티션 사용을 적극 고려.

2. Column NDV (Number of Distinct Values, Selectivity)

- 특정 컬럼에서 서로 다른 값의 개수(NDV). 선택도(selectivity)는 보통 1 / NDV로 근사.

- 특정 조건 컬럼의 필터링 효과(예: WHERE col = x)를 예측.

- NDV가 높으면(예: 주민번호) = 조건의 선택도가 높아, 인덱스 사용이 유리.

- NDV가 낮으면(예: 성별 NDV=2) = 인덱스 효율이 낮아 풀스캔이 나을 수 있음.

ex)

- 테이블 행수 1,000,000, 컬럼 X의 NDV = 100 → 평균 동일값 건수 = 1,000,000 / 100 = 10,000

→ WHERE X = v는 약 10,000건 반환(옵티마이저는 이 값으로 비용 계산)

주의점

- NDV는 전체 분포를 반영하지 못함(값이 일부에 몰려 있을 수 있음). 이런 경우 히스토그램이 필요.

3. Histogram (값 분포 통계)

- 컬럼 값의 분포를 구간(버킷)별로 저장한 통계. 값이 한쪽으로 치우쳐 있거나 특정 값이 고빈도인 경우 정확한 추정을 가능하게 함.

핵심 역할

- 희소성/편중(데이터 스키드)을 포착해서 WHERE 조건에 대한 정확한 예상 행수를 제공.

- 옵티마이저가 특정 값(또는 값 범위)에 대해 더 정확한 비용 계산을 하게 함.

필요한 경우

- 카디널리티는 중간인데 일부 값이 매우 자주 등장할 때 (예: STATUS='N'가 99%, 'Y'가 1%).

- 범위 검색이나 = 연산에서 분포가 비균등할 때.

히스토그램의 형태(개념적)

- 빈도 기반(Frequency): 자주 등장하는 값들을 개별적으로 저장.

- 버킷/균형 기반(Height-balanced / Equi-depth 등): 동일한 행 수를 가지도록 버킷을 나눔.

- (구체적 이름/구현은 DBMS마다 다르지만 목적은 동일)

ex)

- STATUS='Y' 가 실제로 1%인데 히스토그램 없으면 옵티마이저가 평균값을 적용해 잘못된 판단을 내릴 수 있음.

- 히스토그램이 있으면 STATUS='Y'의 선택도(=0.01)를 정확히 계산해 적절한 인덱스/조인 방식을 고른다.

주의점

- 히스토그램 생성은 비용(시간, I/O)이 듦. 너무 많은 컬럼에 무분별하게 만들면 통계 수집 부담과 스토리지 비용 발생.

- 샘플 기반 수집 시 잘못된 샘플링으로 오차 발생 가능.

4. Index Cardinality (인덱스 카디널리티)

- 인덱스에 포함된 서로 다른 키 값의 수. 인덱스 엔트리의 “유니크성” 정도를 나타냄(일종의 NDV 대비 인덱스 관점).

- 컬럼 NDV는 컬럼 자체의 distinct 수지만, 인덱스 카디널리티는 인덱스 키(복합키 포함)의 distinct 수를 본다.

- 인덱스가 포함하는 다른 컬럼/정렬/NULL 처리 때문에 실제 값과 차이가 있을 수 있음.

왜 중요한가?

- 옵티마이저는 인덱스 카디널리티를 보고 인덱스 탐색의 효율(몇 건을 읽어야 하는지)을 예측한다.

- MySQL의 SHOW INDEX 결과의 Cardinality 컬럼은 통계 기반의 근사치로, 인덱스 사용 판단에 영향.

ex)

- 단일 컬럼 인덱스에서 NDV=1,000 → 인덱스 스캔 시 예상 반환 건수 계산에 사용.

- 복합 인덱스 (A,B)에서 A의 NDV가 작고 (A,B)의 카디널리티는 클 수 있음 → 복합 인덱스가 효율적일 수 있음

5. Data Density (데이터 밀도 / Density)

- 값들이 얼마나 균등하게 분포되어 있는지, 흔히 density = 1 / NDV 또는 NDV 대비 빈도 분포의 역산으로 이해한다. (DBMS별 내부 표기법/정의는 조금씩 다를 수 있음)

- 옵티마이저가 인덱스 결합(인덱스 결합 혹은 인덱스 조합)에서 예상 선택도를 근사할 때 density 값을 사용.

- 컬럼 결합(selectivity estimate)을 위해 density값을 곱하거나 사용.

ex)

- NDV=10이면 density ≈ 0.1 → col = v의 기대 확률 10% (간단 근사)

- 실제 분포가 치우쳐 있으면 density는 잘못된 근사가 된다 → 히스토그램/다중컬럼 통계가 필요

6. Column length, NULL 비율 (NULL fraction)

컬럼 길이 (Column length)

- 가변 길이(varchar) vs 고정 길이(char)인 경우, 레코드 크기 추정에 사용되어 I/O 비용 계산에 반영.

- 넓은 컬럼(큰 varchar, text 등)이 많으면 한 블록에 들어가는 로우 수가 줄어들어 I/O 비용이 증가 → 옵티마이저가 블록 스캔 비용을 더 높게 본다.

NULL 비율 (Null fraction)

- 특정 컬럼의 NULL 비율(예: 20% null)도 옵티마이저가 selectivity 예측할 때 사용.

- 인덱스에 NULL이 포함/제외되는 DBMS 차이를 고려해야 함(일부 DB는 NULL을 인덱스에 저장하지 않음).

영향

- NULL이 많은 컬럼에 대해 WHERE col IS NOT NULL 같은 조건의 비용 예측에 사용.

- 부분적 인덱스(partial index)나 필터 인덱스(조건부 인덱스)의 효율 판단에 도움.

  • 통계정보가 중요한 이유

- 옵티마이저는 데이터를 직접 읽지 않음

- 실제 테이블을 스캔해보는게 아니라, 통계정보만 보고 판단

ex)

SELECT * FROM USER WHERE AGE = 25;

- 옵티마이저는 AGE=25 가 100건인지 100만건인지를 직접 읽어보지 않고 통계정보로 추정

- 통계정보가 정확해야 올바른 계획 선택가능

- 통계가 틀리면 잘못된 실행계획 선택(성능저하 발생)

728x90

'DB > sql' 카테고리의 다른 글

[Oracle] 옵티마이저(Optimizer)  (0) 2025.12.24
[Oracle] 파티션(Partition)  (0) 2025.12.23
이기적SQLD(데이터 모델링)1-1  (0) 2023.10.24
오라클 SQL(PL/SQL 제어문)  (0) 2023.10.23
오라클 SQL(PL/SQL1)  (0) 2023.10.20