기술 면접에서 DB 인덱싱에 대한 질문이 들어 왔는데, 만족스러운 답변을 하지 못해 아쉬움이 남았다.
면접에서는 말 못했지만, 인덱싱에 대해 궁금증이 생겨서 고민했던 경험이 있었다. 이전 프로젝트에서 고민했던 이미지 URL을 VARCHAR vs TEXT 중 어떤 것으로 저장할지 결정했던 경험과 연결 지어 내용을 정리해보려고 한다.
VARCHAR vs TEXT의 차이
VARCHAR:
- 인덱싱이 가능하지만 길이 제한이 존재한다.
TEXT:
- 긴 문자열을 저장할 수 있지만, 인덱싱이 제한적이다.
이전 프로젝트에서 저장되는 이미지 URL의 경우 현재는 인덱싱이 필요하지 않지만, 추후 활용할 가능성이 충분하다고 판단하여 VARCHAR를 선택했다.
부족했던 부분: DB 인덱스의 작동 원리에 대한 명확한 이해 부족
이전까지 인덱스가 검색 속도를 향상시킨다는 점은 알고 있었지만, 그 내부적인 작동 원리와 과도한 인덱스가 오히려 성능을 저하시킬 수 있다는 점에 대해 깊이 고민해보지 못했다. 이번 기회를 통해 DB 인덱스가 어떻게 작동하는지와 인덱스가 많아질 때 발생하는 문제를 정리해봤다.
DB인덱스란?
인덱스는 검색 성능을 향상시키기 위한 자료구조이며, 내부적으로 보면 테이블과 유사한 별도의 데이터 구조가 유지된다. 하지만 과도하게 생성된 인덱스는 오히려 성능을 저하시킬 수 있다.
인덱스가 많아질 때 발생하는 문제
1. 조회 시 오버헤드 발생
일반적으로 DBMS는 B+트리(B+Tree) 또는 비트맵 인덱스(Bitmap Index)를 사용하며, 특히 B+트리는 데이터를 범위 기반으로 저장하고 검색 시 여러 노드를 거치는 구조를 가진다. 하지만 인덱스가 많아지면 트리의 깊이(Depth)가 증가하여 탐색 속도가 저하되고, DB가 최적의 인덱스를 선택하는 데 추가적인 시간이 소요될 수 있다.
2. 데이터 변경(INSERT, UPDATE, DELETE) 시 성능 저하
또한, INSERT, UPDATE, DELETE와 같은 데이터 변경 연산은 기존 인덱스를 유지해야 하므로 O(N)에 가까운 추가 오버헤드가 발생하여 O(log N)의 READ 연산보다 성능 저하가 더 크게 나타날 수 있다.
해결책
1. 필요한 인덱스만 유지
아래의 예시 코드와 같이 자주 사용하는 WHERE, JOIN, ORDER BY, GROUP BY 조건에서만 인덱스를 설정하여 최소한의 인덱스만 유지하는 것이 중요하다.
-- 테이블에서 특정 사용자 ID로 자주 검색하는 경우
CREATE INDEX idx_users_user_id ON users(user_id);
-- 실행 계획 확인
EXPLAIN SELECT * FROM users WHERE user_id = 123;
-- 기존에 존재하는 인덱스 확인
SHOW INDEX FROM users;
-- 사용되지 않는 인덱스 삭제
DROP INDEX idx_old_index ON users;
2. 복합 인덱스(Composite Index) 활용
단일 인덱스를 조회하게 되면 두 개의 인덱스를 각각 탐색하기 때문에 비효율적이다. 아래의 코드처럼 복합 인덱스를 생성하여 두 개의 인덱스를 한번의 인덱싱으로 해결할 수 있어 성능을 향상시킬 수 있다.
-- 잘못된 방식: 개별 인덱스를 여러 개 생성
CREATE INDEX idx_users_user_id ON users(user_id);
CREATE INDEX idx_users_created_at ON users(created_at);
-- 올바른 방식: 복합 인덱스를 생성하여 한 번에 검색 가능하게 함
CREATE INDEX idx_users_user_created ON users(user_id, created_at);
-- 실행 계획 확인
EXPLAIN SELECT * FROM users WHERE user_id = 123 AND created_at > '2024-01-01';
최종정리
DB 인덱스는 B+트리 구조를 사용하여 데이터를 범위 기반으로 저장하지만, 인덱스가 많아지면 트리의 Depth가 증가하여 탐색 속도가 저하될 수 있다. 이를 방지하기 위해 EXPLAIN을 활용하여 인덱스 사용 여부를 점검하고, 최소한의 인덱스만 유지하는 것이 중요하다. 또한, 복합 인덱스를 활용하면 조회 횟수를 줄여 성능을 더욱 향상시킬 수 있다.