인덱스는 데이터베이스를 효율적으로 검색할 수 있도록 테이블의 특정 컬럼에 대한 별도의 데이터 구조를 생성하는 기술이다. 쉽게 말하면 인덱스는 책의 색인처럼 작동하여 원하는 데이터를 더 빠르게 찾도록 도와준다고 보면 된다.
인덱스는 보통 B-Tree 또는 Hash 자료구조를 기반으로 만들어진다.
데이터베이스는 테이블의 데이터를 정렬하여 인덱스를 생성하고, 특정 컬럼의 값과 해당 데이터가 저장된 위치를 매핑한다. 이 때 검색시 전체 테이블을 스캔하는 대신, 인덱스를 먼저 조회하여 필용한 데이터를 효율적으로 찾는 것이다.
예시) 고객 관리 시스템에서 고객 ID에 인덱스를 설정하면 특정 고객 ID로 조회하는 작업이 훨씬 빨라진다.
예시) 매일 수백만 개의 트랜젝션 데이터가 추가되는 테이블에 과도한 인덱스를 설정하면, 삽입 작업이 느려지고 인덱스 크기 관리가 어려워질 수 있다.
SELECT * FROM users WHERE email = 'example@example.com';
위의 쿼리가 주된 경우에는 email에 인덱스를 설정하면 검색 속도가 향상된다.
인덱스는 고유한 값이 많은 만큼 효과적이다.
예시) 주민등록번호, 이메일 주소처럼 고유한 값이 많은 컬럼은 인덱스 효과가 크다.
이에 반해 삽입/수정이 많은 컬럼에는 데이터가 변경될 때마다 인덱스가 업데이트되므로 쓰기 성능이 저하될 수 있기에 신중하게 선택해야 한다.
실무에서 가장 많이 사용하는 복합인덱스는 순서에 따라서도 인덱스 적용이 달라지기 때문에 신중하게 생성해야 한다.
즉 왼쪽 부터 연속인 필드에 대해서는 인덱스를 사용할 수 있고 오른쪽으로부터는 사용이 불가하다는 것을 명심해야한다.
예시)
SELECT * FROM orders WHERE user_id = 123 AND order_date > '2024-01-01';
위와 같은 쿼리가 있다면 user_id, order_date 순으로 두어야 효율적이고, 또 user_id와 같은 경우에는 따로 단독 쿼리로도 사용이 되기 때문에 인덱스가 적게 생성될 수 있다.
그 밖에도 Distinct, Join에서도 성능 최적화를 줄 수 있고 실무에서는 복합인덱스 사용을 피할 수가 없다.
복합 인덱스는 메모리 사용량이 적지 않으므로 적절하게 사용되야 하는데 이 때 팁은 생성하고 데이터베이스 실행 계획(EXPLAIN)을 사용하여 몇번의 key를 거쳤는지 몇번의 레코드들을 거쳤는지 확인해보고 성능 향상이 이뤄냈을 때 생성하는 것이 좋다.
개발을 시작할 초기에는 인덱스의 중요성을 그렇게 많이 생각하지 못하고 쿼리를 짰던적이 많았다. 그러다가 대규모 파이프라인 개발을 해보고 내가 만든 쿼리에 인덱스 생성이 안되어 있어서 서버의 Pods이 죽어버린☠️ 그런 안타까운 사연을 한번 겪고 난 후에는 쿼리를 만들거나 엔티티를 만들 때 주로 사용되는 필드가 무엇인지 인덱스를 어떻게 생성해야할지 생각을 한다....
이 포스팅을 읽는 분들은 그러한 실수를 하지 않기를 바라며 이번 포스팅을 마친다~~