(새 문서: == Cardinality (카디널리티) 와 Selectivity (선택도) {{핵심 |제목= * Cardinality (카디널리티) ** 특정 연산이나 조건에서 반환되는 예상 행의 개수 ** 절대적인 수치 (행 개수) ** 실행 계획의 “Rows” 컬럼에 표시됨 *:-------------- * Selectivity (선택도) ** 전체 행 중에서 조건을 만족하는 행의 비율 ** 상대적인 비율 (0 ~ 1 사이의 값, 또는 0% ~ 100%) ** 조건의 “선택적” 정도를 나타...) |
편집 요약 없음 |
||
| 1번째 줄: | 1번째 줄: | ||
== Cardinality (카디널리티) 와 Selectivity (선택도) | == Cardinality (카디널리티) 와 Selectivity (선택도) == | ||
{{핵심 | {{핵심 | ||
|제목= | |제목= | ||
2025년 10월 24일 (금) 13:01 기준 최신판
Cardinality (카디널리티) 와 Selectivity (선택도)
vpn_key * Cardinality (카디널리티)
- 특정 연산이나 조건에서 반환되는 예상 행의 개수
- 절대적인 수치 (행 개수)
- 실행 계획의 “Rows” 컬럼에 표시됨
- --------------
- Selectivity (선택도)
- 전체 행 중에서 조건을 만족하는 행의 비율
- 상대적인 비율 (0 ~ 1 사이의 값, 또는 0% ~ 100%)
- 조건의 “선택적” 정도를 나타냄
playlist_add_check
Cardinality = Total Rows × Selectivity Selectivity = Cardinality / Total Rows
실무 예제
- 예제 1: 단순 테이블
-- 직원 테이블
CREATE TABLE employees (
emp_id NUMBER,
dept_id NUMBER,
salary NUMBER,
status VARCHAR2(20)
);
-- 통계 정보
-- Total Rows: 10,000명
-- dept_id = 10: 500명
-- salary > 5000: 3,000명
-- status = 'ACTIVE': 9,000명
-- Query 1
SELECT * FROM employees WHERE dept_id = 10;
- Selectivity = 500 / 10,000 = 0.05 (5%)
- Cardinality = 500 (행)
-- Query 2
SELECT * FROM employees WHERE salary > 5000;
- Selectivity = 3,000 / 10,000 = 0.3 (30%)
- Cardinality = 3,000 (행)
-- Query 3
SELECT * FROM employees WHERE status = 'ACTIVE';
- Selectivity = 9,000 / 10,000 = 0.9 (90%)
- Cardinality = 9,000 (행)
= 실행 계획 확인
-- 통계 수집
EXEC DBMS_STATS.GATHER_TABLE_STATS('SCOTT', 'EMPLOYEES');
-- 실행 계획 확인
EXPLAIN PLAN FOR
SELECT * FROM employees WHERE dept_id = 10;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
- 실행 계획 결과:
-------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
-------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 500 | 5000 | 10 (0)|
|* 1 | TABLE ACCESS FULL| EMPLOYEES | 500 | 5000 | 10 (0)|
-------------------------------------------------------------------------
Predicate Information:
1 - filter("DEPT_ID"=10)
Rows = 500 ← 이것이 Cardinality
Selectivity 계산 공식
1. 등호(=) 조건
-- WHERE column = value Selectivity = 1 / NUM_DISTINCT 예: dept_id의 distinct 값이 20개 Selectivity = 1 / 20 = 0.05
2. 범위 조건
-- WHERE column > value
Selectivity = (MAX_VALUE - value) / (MAX_VALUE - MIN_VALUE)
예: salary BETWEEN 3000 AND 10000
조건: salary > 5000
Selectivity = (10000 - 5000) / (10000 - 3000) = 5000/7000 ≈ 0.71
3. NULL 조건
-- WHERE column IS NULL Selectivity = NUM_NULLS / NUM_ROWS 예: 10,000행 중 500개가 NULL Selectivity = 500 / 10,000 = 0.05
4. 복합 조건 (AND)
-- WHERE col1 = 10 AND col2 = 'A' Selectivity = Selectivity(col1) × Selectivity(col2) 예: Selectivity(col1) = 0.05 Selectivity(col2) = 0.1 Total Selectivity = 0.05 × 0.1 = 0.005 (0.5%) Cardinality = 10,000 × 0.005 = 50
5. 복합 조건 (OR)
-- WHERE col1 = 10 OR col2 = 'A' Selectivity = Sel(col1) + Sel(col2) - (Sel(col1) × Sel(col2)) 예: Selectivity(col1) = 0.05 Selectivity(col2) = 0.1 Total Selectivity = 0.05 + 0.1 - (0.05 × 0.1) = 0.145 Cardinality = 10,000 × 0.145 = 1,450
통계 정보에서 확인
-- Selectivity 관련 통계
SELECT table_name,
column_name,
num_distinct, -- distinct 값 개수
num_nulls, -- NULL 개수
density, -- 1/num_distinct (Selectivity)
num_rows -- 전체 행 수
FROM user_tab_col_statistics
WHERE table_name = 'EMPLOYEES';
- 결과 예시:
COLUMN_NAME NUM_DISTINCT NUM_NULLS DENSITY NUM_ROWS --------------------------------------------------------- EMP_ID 10000 0 0.0001 10000 DEPT_ID 20 0 0.05 10000 ← Selectivity SALARY 500 100 0.002 10000 STATUS 2 0 0.5 10000
실무에서의 중요성
1. 인덱스 생성 판단
-- Selectivity가 낮을수록 (선택적일수록) 인덱스 효과 좋음 -- 좋은 경우 (Selectivity: 0.001%) CREATE INDEX idx_emp_id ON employees(emp_id); -- emp_id는 고유값, 조회 시 1-2건만 반환 -- 나쁜 경우 (Selectivity: 90%) CREATE INDEX idx_status ON employees(status); -- status는 ACTIVE/INACTIVE 2개 값, 조회 시 9000건 반환 -- Full Table Scan이 더 효율적
2. 조인 순서 결정
-- Cardinality가 작은 테이블을 먼저 처리 SELECT /*+ LEADING(d e) */ * FROM departments d JOIN employees e ON d.dept_id = e.dept_id WHERE d.location = 'SEOUL'; -- d 테이블의 Cardinality: 10 (Selectivity 1%) -- e 테이블의 Cardinality: 10000 (Selectivity 100%) -- → departments를 먼저 필터링하는 것이 효율적
3. 통계 정확도 확인
-- 실제 Cardinality vs 예상 Cardinality SELECT /*+ GATHER_PLAN_STATISTICS */ * FROM employees WHERE dept_id = 10; SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(format=>'ALLSTATS LAST'));
- 결과:
------------------------------------------------------------------- | Id | Operation | Name | Starts | E-Rows | A-Rows | ... ------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | 520 | ... |* 1 | TABLE ACCESS FULL | EMP | 1 | 500 | 520 | ... ------------------------------------------------------------------- E-Rows: 500 ← 예상 Cardinality (Estimated) A-Rows: 520 ← 실제 Cardinality (Actual) 차이: 4% (통계가 정확함)
핵심 차이점 요약
|구분 |Cardinality |Selectivity| |-------|--------------|-----------| |**의미** |반환되는 행의 개수 |선택되는 행의 비율 | |**단위** |행 (rows) |비율 (0~1) | |**타입** |절대값 |상대값 | |**사용처**|실행 계획, Cost 계산|조건 효율성 판단 | |**예시** |500 rows |5% (0.05) |
- 실무 팁:** Selectivity가 5% 이하일 때 인덱스 사용이 효과적이고, Cardinality는 조인 순서와 메모리 할당에 영향을 줍니다!