DB를 사용하면서 데이터 양에 따라 실행 결과의 속도가 차이가 나는 것을 알고 있었다. 데이터의 양이 증가할 수록 실행 속도는 느려지고 WHERE 조건에서 필요한 데이터만 추출 후 사용하는 것이 좋다고 들었는데 보다 쿼리의 성능을 높이는 중요한 것은 인덱스를 활용한다는 것을 알게되었다.
인덱스란 추가적인 쓰기 작업과 저장 공간을 활용하여 데이터베이스 테이블의 검색 속도를 향상시키기 위한 자료구조이다. 만약 우리가 책에서 원하는 내용을 찾는다고 하면, 책의 모든 페이지를 찾아 보는것은 오랜 시간이 걸린다. 그렇기 때문에 책의 저자들은 책의 맨 앞 또는 맨 뒤에 색인을 추가하는데, 데이터베이스의 index는 책의 색인과 같다.
데이터베이스에서도 테이블의 모든 데이터를 검색하면 시간이 오래 걸리기 때문에 데이터와 데이터의 위치를 포함한 자료구조를 생성하여 빠르게 조회할 수 있도록 돕고 있다.
인덱스의 가장 큰 특징은 데이터들이 정렬이 되어있다는 점이다. 이러한 특징으로 인해 조건 검색이라는 영역에서 큰 장점이 된다.
테이블을 만들고 데이터를 저장하면 테이블의 레코드는 내부적으로 순서 없이 저장이 된다.
WHERE절에 특정 조건에 맞는 데이터들을 찾아야 하는 경우 레코드의 처음부터 끝까지 다 읽어서 검색 조건과 동일한지 비교해야 한다. 이것을 풀 테이블 스캔, 풀 스캔이라고 한다.
하지만 인덱스 테이블 스캔 시 인덱스 테이블은 데이터들이 정렬되어 저장되어 있기 때문에 해당 조건에 맞는 데이터를 빠르게 찾아낼 수 있다.
해당 이규가 인덱스를 사용하는 가장 큰 이유다.
인덱스를 사용하면 ORDER BY에 의한 정렬 과정을 피할 수 있다. ORDER BY는 부하가 많이 걸리는 작업이다. 메모리에서 정렬이 이루어지고 메모리보다 큰 작업이 필요하다면 디스크I/O(HDD에 저장되는 것) 도 추가적으로 발생되기 때문이다.
하지만 인덱스를 사용하면 이미 정렬이 되어 있기 때문에 이러한 전반적인 자원의 소모를 하지 않고 그대로 가져오기만 하면 된다.
이것 또한 데이터가 정렬되어 있기에 얻을 수 있는 장점이다. 레코드의 끝, 시작값을 한 건씩만 가져오면 되기 때문에 풀 테이블 스캔으로 테이블 모두를 확인하는 것 보다 효율적으로 찾을 수 있다.
인덱스의 장점이 있지만 담점도 있다. 가장 큰 단점은 정렬된 상태를 계속 유지시켜줘야 하는데, 만약 레코드내에 데이터 값이 빠뀐다면 악영향을 준다.
INSERT, UPDATE, DELETE를 통해 데이터가 추가되거나 값이 바뀐다면 인덱스 테이블 내에 있는 값들을 다시 정렬을 해야 한다. 그리고 위에 사진처럼 인덱스 테이블, 원본 테이블 이렇게 두 군데의 데이터 수정 작업을 해줘야 한다는 단점도 발생한다. 그렇기 때문에 DML이 빈번한 테이블보다 검색을 위주로 하는 테이블에 인덱스를 생성하는 것이 좋다.
검색을 위주로 하는 테이블에 인덱스를 생성하는 것이 좋지만 무조건 검색 시에도 인덱스가 좋은 것은 아니다. 인덱스는 테이블의 전체 데이터 중에서 10~15% 이하의 데이터를 처리하는 경우에만 효율적이고 그 이상의 데이터를 처리할 땐 인덱스를 사용하지 않는 것이 더 낫다.