[소프트웨어 개발자 면접] 시스템 디자인 - 인덱스 Index
쿼리 5초를 수십ms로 줄인 인덱스 경험과, 인덱스를 남발했다가 쓰기 성능이 폭락한 실패 경험을 정리합니다. 트레이드오프, 과도한 인덱스 감사 방법, 빅데이터 환경 적용까지 다룹니다.
실무에서 데이터베이스 조회 속도가 느려 고생한 적이 있습니다. 수백만 건의 주문 데이터를 조회하는 쿼리가 5초 넘게 걸렸고, 처음에는 쿼리 자체를 최적화하거나 불필요한 JOIN을 줄이는 방향으로 접근했습니다. 그래도 속도가 나아지지 않았습니다. 그때 인덱스를 제대로 설정하고 나서야 응답 시간이 수십 밀리초 수준으로 줄었습니다. 그 경험 이후 인덱스를 단순한 성능 도구가 아니라 시스템 설계의 핵심 개념으로 바라보게 됐습니다.
실무나 인터뷰에서 시스템 디자인 설계 시 RDB(관계형 데이터베이스)를 선택했다면, 인덱스를 충분히 이해하고 있어야 원하는 결과를 도출할 수 있습니다.

데이터베이스 인덱스
인덱스는 데이터베이스 테이블의 동작 속도를 높여주는 자료 구조입니다. 데이터 검색 속도를 향상시키는 대신, 스토리지 오버헤드 증가와 쓰기 속도 저하라는 트레이드오프가 발생합니다. 쓰기 속도가 느려지는 이유는 데이터를 쓸 때 인덱스도 함께 업데이트해야 하기 때문입니다.
인덱스는 책의 목차와 같은 역할을 합니다. 책 본문을 처음부터 한 장씩 넘기지 않고 목차에서 페이지 번호를 확인한 뒤 바로 이동하는 것처럼, 인덱스를 활용하면 테이블 전체를 스캔하지 않고 원하는 데이터를 곧바로 꺼낼 수 있습니다. 테이블의 특정 열(column)에 인덱스를 생성하면, 그 열의 값과 전체 행에 대한 포인터가 별도 구조에 저장됩니다. 참고로 인덱스는 key-value 구조로만 구성되어 원본 테이블의 다른 정보를 포함하지 않으므로, 일반적으로 테이블 자체보다 훨씬 적은 디스크 공간을 사용합니다.

인덱스의 함정: 과도한 인덱스
조회 속도 개선에 성공하고 나서, 저는 반대 실수를 저질렀습니다. 자주 조회되는 열마다 인덱스를 추가하다 보니, 어느 순간 테이블 하나에 인덱스가 10개를 넘어 있었습니다. 처음에는 읽기 성능이 좋아 만족했는데, 배치 작업으로 대량 데이터를 삽입하는 순간 속도가 눈에 띄게 느려졌습니다. 원인은 인덱스 과부하였습니다. 데이터 한 행을 삽입할 때마다 10개의 인덱스를 전부 업데이트해야 했던 것입니다.
나중에 알게 된 교훈이 있습니다. 나쁜 인덱스는 인덱스가 없는 것보다 더 나쁩니다. 사용되지 않는 인덱스는 스토리지를 낭비하고 쓰기 성능을 갉아먹으면서도 아무런 이득을 주지 않습니다. 문제는 이 손해가 조용히 쌓인다는 점입니다. EXPLAIN ANALYZE(PostgreSQL) 또는 EXPLAIN(MySQL)으로 실행 계획을 확인하거나, pg_stat_user_indexes 같은 시스템 테이블로 인덱스 사용 빈도를 주기적으로 점검하는 것이 필수입니다.
Big Data와 인덱스
인덱스의 개념은 전통적인 관계형 데이터베이스를 넘어 빅데이터 환경에도 동일하게 적용됩니다. 다만 이 규모에서는 사용자가 데이터에 어떻게 접근할 것인지를 미리 신중하게 설계해야 합니다.
수 테라바이트(TB) 크기의 데이터에서 1킬로바이트(KB) 단위의 페이로드를 찾아야 하는 상황을 생각해봤습니다. 인덱스 없이 전체를 순차 탐색하면 납득할 수 있는 시간 안에 결과를 얻기란 사실상 불가능합니다. 더구나 빅데이터는 여러 서버에 물리적으로 분산되어 있는 경우가 대부분이어서, 데이터의 정확한 물리적 위치를 찾을 수 있는 수단이 반드시 필요합니다. 인덱스가 그 역할을 담당합니다.
마무리
시스템 디자인 면접에서 데이터 계층을 다루는 부분이 실제 합격 여부를 가르는 경우가 많습니다. 인덱스를 "빠르게 만드는 도구" 정도로만 알고 들어가면, 트레이드오프 질문이 나왔을 때 막힙니다. 읽기 성능과 쓰기 성능 사이의 균형, 불필요한 인덱스를 걷어내는 시점, 빅데이터 환경에서의 인덱스 전략까지 설명할 수 있다면, 인덱스 하나로 면접 상당 부분을 가져올 수 있습니다. 인덱스를 이해하면 맵리듀스나 데이터 스트림 처리 개념도 훨씬 자연스럽게 연결됩니다.