데이터베이스 빠른 검색을 위한 인덱스(INDEX)

 

우리가 데이터베이스를 통해 여러가지 작업을 할때 빠질수없는 쿼리문중 하나인 WHERE 조건을 자주 접해봤을것이다

서비스를 운영하면서 많은양의 데이터가 저장된 데이터베이스 테이블에서 원하는 데이터를 가져오기위해서는 일반적으로 Full Scan을 통해서 가져오게되는데

 

Full Scan이란 모든데이터를 전부 한번씩 보고 원하는 데이터를 찾는것을 말하는데 이는 곧 100만건의 데이터가 저장되어있다면 100만건 전부다 확인하여 원하는 데이터를 구한다는 것을 의미한다

이렇게 Full Scan으로 검색하는것은 적은 데이터에서는 그렇게 문제될것은 없지만 데이터가 많아진다면 검색해야될 데이터도 같이 늘어나게되므로 비효율적이다

 

만약 2개이상의 조건이 걸려있게되면 검색시간은 기하급수적으로 늘어나게된다

이것을 해결하기위해서 Index라는것을 컬럼에 걸수있는데 우선 Index가 무엇인지에 대해부터 알아보도록 하자

 

 

 

 

Index란 검색속도를 향상시키기 위한 자료구조로써 칼럼에 인덱스를 적용하하게되면 값들이 정렬되어 저장되고 각각의 데이터들은 테이블의 원래 데이터를 pointer로 가르키게된다

 

이렇게되면 만약 원하는 데이터를 훨씬 빠른속도로 가져올수있게되는데 만약 100만건의 데이터가 있을경우 Where나 Order, Group By 등에 걸게되면 안걸었을경우 100만건 전부 Full Scan하게 되지만 인덱스를 적용시키게되면

100만건의 가운데값인 50만번째에 있는 데이터를 비교하게되고 해당 데이터가 높은지 낮은지 확인하게된다

 

비교하는 값보다 더 높을경우 위에있는 데이터를 더 볼필요없이 50만건을 전부 짜른다

그다음 나머지 50만건의 데이터중 25만번째에있는 데이터를 같은 형식으로 비교하고 짜르고를 반복하여 원하는 결과값을 찾는다

 

이렇게 검색대상의 레코드의 범위를 줄여나가 검색속도를 개선하며, 중복데이터를 방지함과 동시에 특정컬럼의 유일성을 보장할수있게된다

 

" 검색 효율을 높혀주는것은 좋은거아니야? "

아쉽게도 모든것에는 트레이드오프가 있는법 인덱스에도 여러가지 단점들이 존재한다

첫번째로 위에서 말했듯이 인덱스를 따로 생성하기 위해서는 추가적인 저장공간이 필요하다

그리고 만약 삽입, 삭제, 수정 작업이 일어날경우 이에따른 인덱스도 새롭게 업데이트 해야하므로 이러한 작업이 자주이루어진다면 오히려 성능저하가 발생할수도 있다

 

만약 내가 검색성능을 높히기위해서 인덱스를 적용시키고 싶을때는 데이터의 빈번한 변경이 일어나는지 잘따져보고 적용시키면 성능개선에 도움이 될수있다

 

대표적으로 인덱스를 사용하는 경우는 다음과같다

대량의 데이터를 검색해야하는 경우에는 인덱스를 사용하는것이 검색속도 향상에 도움이된다 Full Scan으로 모든값들을 전부 스캔하는것은 비효율적이기 때문에 이경우에는 인덱스를 걸어주도록 하자

그다음은 정렬된 결과를 출력해야하는경우나, 데이터를 정렬해야하는경우에 인덱스를 고려해보는것도 좋은선택이다

왜냐하면 인덱스를 사용해 데이터를 정렬하면 빠르게 정렬된 결과값을 출력할수 있기때문이다

 

그다음은 조인연산을 수행할때 인덱스를 생성하게되면 조인대상 테이블의 데이터를 빠르게 검색하게해준다

 

마지막으로 검색빈도가 높은 칼럼에 대해서 인덱스를 생성하여 검색속도를 향상시키는것이 좋은 선택이라고 생각한다

 

 

인덱스의 자료구조에는 여러가지가있는데 크게 해시테이블, B-Tree 와 B+Tree로 이루어진다

첫번째로 해시테이블은 Key와 Hash Value 쌍으로 이루어진 자료구조로써 시간복잡도는 O(1)로써 매우 빠르게 검색할수있는것이 특징인 자료구조이다

 

하지만 검색속도가 매우빠르지만 부등호 연산이 자주사용되는 곳에서는 해시테이블을 굳이 사용하진않는다

 

그다음 가장 널리쓰이고 많이아는 B-Tree로써 노드내의 데이터들이 항상 정렬된 상태이며, 데이터와 데이터사이의 범위를 이용해 자식노드를 가지게된다 이는 곧 한노드가 여러개의 키를 가질수도있고 키에 해당하는 데이터와 같이 가지고있다는것이 특징이다

 

그다음 B+Tree는 위에 언급한 B-Tree의 변형되어있는 구조이며 모든 노드가 연결리스트로 연결되있으며, 범위검색이나 순차검색에 효율적이다

 

만약 서비스의 검색성능최적화를 위해 인덱스를 고려할때는 위에 여러가지 상황을 따져보며 적용해보면 유의미한 성능향상에 도움이 될수도있다