본문 바로가기
기타

[SQL] Cardinality vs Selectivity (카디널리티와 선택도) 차이점 및 구하는 쿼리

by A6K 2021. 8. 3.

데이터베이스나 빅데이터 분야에서 '카디널리티(Cardinality)'와 '선택도(Selectivity)'는 자주 언급되는 용어다. 이 용어의 차이점을 정확히 알고 있어야 가지고 있는 데이터의 특성을 잘 파악할 수 있다.

카디널리티와 선택도는 절대적인 수치가 아닌 두 개의 데이터 집합의 특성을 비교하는 상대적인 개념으로 사용해야한다.

카디널리티(Cardinality)

카디널리티는 특정 데이터 집합에서 유니크한 값의 개수를 의미한다. 예를 들어 데이터베이스의 테이블의 '성별' 컬럼의 경우 생물학적인 성별을 고려할 때 '남자'와 '여자'로 구성된다. 성별 컬럼의 카디널리티는 2라고 할 수 있다.

반대로 주민등록 번호 같이 PK 혹은 CandidateKey는 테이블에 존재하는 모든 레코드들에 유니크할 수 있다. 이 경우 주민등록 번호 컬럼의 카디널리티는 테이블에 들어있는 레코드의 개수가 된다.

오라클에서는 다음 쿼리로 특정 컬럼의  카디널리티를 구할 수 있다.

select count(distinct (deptno)) from employee;

선택도(Selectivity)

선택도는 카디널리티로부터 계산할 수 있다. 

Selectivity = Cardinality / Total Number Of Records

선택도는 데이터의 집합에서 특정 값을 얼마나 잘 골라낼 수 있는지에 대한 지표라고 할 수 있다. 선택도가 1이라는 뜻은 모든 값이 유니크하다는 의미다.

선택도는 테이블의 인덱스를 생성할 때, 어떤 컬럼에 생성하면 좋을지 고를 때 자주 사용한다. 선택도가 높은 컬럼에 인덱스를 생성하면 인덱스가 특정 레코드를 잘 골라내서 인덱스의 효율이 높아진다. 극단적으로는 PK나 Candidate Key가 거의 1에 가까운 선택도를 갖게 되고 인덱스를 걸어주면 좋다. (UniqueKey 값도 비슷하다)

반대로 선택도가 낮은 컬럼에 인덱스를 걸게 되면 인덱스 효율이 낮아지게 되고, 결국 풀 테이블 스캔으로 플랜이 풀리게 될 수 있다.

오라클에서 선택도를 구하는 쿼리는 다음과 같다.

SELECT (distinct_keys / num_rows) AS Selectivity
FROM dba_indexes
WHERE index_name like 'Index_Name' and Owner ='Table_Owner';

오라클이 제공하는 카탈로그 뷰 중 'dba_indexes" 뷰를 조회하면 특정 인덱스의 선택도를 알 수 있다.

데이터베이스에서 인덱스의 선택도를 높이는 방법은 간단하다. 두 개 이상의 컬럼을 조합해서 인덱스를 걸어주면, 조합된 인덱스 키의 카디널리티가 증가하고 결국 선택도도 증가하여 효율이 좋은 인덱스가 된다. (대신 인덱스 키를 많이 사용하여 공간 효율이 낮아지게 된다.)

댓글