본문 바로가기
CS

CS 스터디 (DB) 19 - NULL 은 인덱스를 탈까요?

by gentle-tiger 2025. 5. 20.

NULL 은 인덱스를 탈까요?

SQL에서 NULL 값이 인덱스를 사용하는지는 DBMS마다 다릅니다. Oracle은 기본적으로 B-tree 인덱스에서 NULL을 인덱싱하지 않기 때문에, WHERE 절에서 NULL 조건은 인덱스를 사용하지 못합니다. 하지만 비트맵 인덱스를 사용하면 NULL도 포함시킬 수 있습니다.

반면, MySQL(InnoDB)과 PostgreSQL은 B-tree 인덱스에 NULL 값을 포함하므로, 해당 조건에서도 인덱스를 사용할 수 있습니다. 또한, partial index를 통해 NULL이나 NOT NULL 값에만 인덱스를 적용할 수도 있습니다. SQL Server 역시 NULL을 인덱싱하며, UNIQUE 인덱스에서도 중복된 NULL 값이 허용됩니다.

 

 

 

인덱스에 NULL 포함 장단점

장점 

1. NULL 조건 검색 시 인덱스 활용으로 테이블 풀 스캔을 줄일 수 있습니다.

2. 일부 DBMS의 Partial Index 지원으로, 필요한 조건만 인덱싱하여 성능과 자원 사용을 최적화할 수 있습니다.

3. ORDER BY, GROUP BY 등에서 NULL 포함 컬럼을 인덱스로 정렬/그룹화 최적화할 수 있습니다.

 

단점 

1. 조회 대상이 전체의 약 20~25%를 초과할 경우, 옵티마이저가 인덱스보다 풀 스캔을 선호할 수 있습니다.

2. NULL 값이 많으면 인덱스 크기 증가캐시 효율 저하로 이어질 수 있습니다.

3. INSERT, UPDATE, DELETE 시 인덱스 유지 비용이 증가하여 쓰기 성능에 영향을 줄 수 있습니다.

4.  NULL 값의 분포가 불균형하거나 예측 불가능한 경우, 실행 계획이 불안정해질 수 있습니다.

 

 

사용 예시 

1. Oracle-비트맵 인덱스 사용

CREATE BITMAP INDEX idx_user_status ON users(status);
-- status가 NULL인 조건도 인덱스를 사용할 수 있음
SELECT * FROM users WHERE status IS NULL;

 

2. PostgreSQL-Partial Index 활용

CREATE INDEX idx_user_deleted_null ON users(deleted_at) WHERE deleted_at IS NULL;
-- deleted_at이 NULL인 경우에만 인덱스 사용
SELECT * FROM users WHERE deleted_at IS NULL;

 

3. MySQL-기본 B-tree 인덱스 (InnoDB)

CREATE INDEX idx_user_email ON users(email);
-- email이 NULL이어도 인덱스에 포함됨
SELECT * FROM users WHERE email IS NULL;