카디널리티
데이터베이스에서 카디널리티는 컬럼 값의 중복도를 나타내는 지표로, 인덱스 성능에 직결되는 개념입니다.
카디널리티란?
카디널리티 = 컬럼에서 유니크한 값의 수
성별 컬럼 : [남, 여] → 카디널리티 = 2 (낮음)
학년 컬럼 : [1, 2, 3, 4] → 카디널리티 = 4
이메일 컬럼: [a@.., b@.., c@.., ...] → 카디널리티 = 행 수와 거의 동일 (높음)
카디널리티와 인덱스 효율
| 카디널리티 | 예시 컬럼 | 인덱스 효율 |
|---|---|---|
| 높음 | PK, 이메일, 주민번호 | O 매우 효율적 |
| 중간 | 나이, 지역, 학과 | 상황에 따라 다름 |
| 낮음 | 성별, 활성여부(Y/N) | X 비효율적 |
왜 카디널리티가 높아야 인덱스가 효율적일까?
전체 데이터 : 1,000,000건
-- 카디널리티 낮음 (성별)
WHERE gender = '남' → 약 500,000건 반환
인덱스 탐색 후 절반을 또 읽어야 함 → Full Scan이 오히려 빠를 수 있음 X
-- 카디널리티 높음 (이메일)
WHERE email = 'kim@test.com' → 1건 반환
인덱스로 정확히 1건만 탐색 O
복합 인덱스에서의 카디널리티
복합 인덱스 생성 시 카디널리티가 높은 컬럼을 앞에 배치해야 합니다.
-- X 비효율: 카디널리티 낮은 컬럼이 앞
INDEX (gender, email)
-- O 효율: 카디널리티 높은 컬럼이 앞
INDEX (email, gender)
INDEX (gender, email) 탐색 과정:
1단계: gender = '남' → 500,000건으로 좁혀짐
2단계: email = 'kim@..' → 1건
INDEX (email, gender) 탐색 과정:
1단계: email = 'kim@..' → 1건으로 바로 좁혀짐 O
카디널리티 확인 방법
-- 컬럼별 카디널리티 확인
SELECT
COUNT(DISTINCT gender) AS gender_cardinality, -- 2
COUNT(DISTINCT age) AS age_cardinality, -- ~80
COUNT(DISTINCT email) AS email_cardinality -- ~1,000,000
FROM user;
-- 인덱스 카디널리티 확인
SHOW INDEX FROM user;
-- Cardinality 컬럼에서 확인 가능
카디널리티가 낮은 컬럼은 인덱스 대신 파티셔닝을 고려하는 것이 좋습니다.