올리브영 프로젝트를 진행하면서 최근에 글 작성이 굉장히 뜸해졌다.
대형 프로젝트를 처음으로 맡아 진행하면서 많은 것을 배웠고 앞으로 당장 해야 할 것들을 찾은 시간이었던 것 같다.
내가 생각한 당장 해야 할 공부는 데이터베이스에 관련된 공부라고 생각한다. 특히 큰 프로젝트 일수록 그 안에 있는 데이터베이스의 양이 많아지게 되므로 데이터베이스 탐색 성능 최적화는 당연하게 따라와야 하는 부분임을 느꼈다.
탐색 성능을 최적화 하기 위한 방법은 여러가지가 있지만 그 중에서 오늘은 DB 인덱싱에 관하여 공부한 것을 포스팅 하고자 한다.
기본적으로 테이블에 저장되어 있는 row들의 저장 형태는 선형적인 구조로 되어있지만 인덱싱을 하게되면
DB 엔진에 따라 다르지만 기본적으로 크게 Hash형식과 B-tree 구조로 바뀌게 된다. 내가 프로젝트를 진행했던 DB 엔진은 Mysql을 사용했기 때문에 B-tree구조에 대해 구체적으로 적어보려 한다.
테이블의 구조를 선형적인 구조에서 인덱싱을 이용해 B-tree 구조로 바꾸게 되면 얻을 수 있는 이득은 무엇일까?
- 검색 속도가 굉장히 빠르다.
예를들어 employee Hyeok을 찾으려고 할 때 이진트리 탐색 방법을 따라 찾게 되면 Root Node부터 시작해서 Left sub-tree 또는
Right sub-tree 따라 아래로 탐색을 하게된다. Left sub-tree에는 Right sub-tree보다 작은 값들이 저장되기 때문에 이 방법을 따르면 어떠한 쿼리를 사용하더라도 대략적으로 비슷한 시간안에 결과 값이 도출된다.
데이터베이스 인덱싱은 특정 키, 키와 관련된 값을 가지고 있지 않다.
즉, key-value 쌍이 아니라는 의미이다.
실제 데이터 레코드를 참조한 값을 가지고 있는데 그것은 키와 값을 같이 가지고 있는 페이로드라고 불린다.
또한 인덱싱은 다른 컬럼의 모든 데이터 값을 가지고 있지도 않는다.
하지만 ROWID라는 모든 컬럼의 각각의 내부 식별자를 가지고 있는데 이것은 primary key가 아니며
디스크로부터 가져온 테이블로 돌아가기 위한 수단일 뿐이다.
인덱스 처리된 데이터는 메모리에 저장되고, 그렇지 않은 데이터는 디스크 저장되어있다.
그렇다면 인덱스를 전부 사용하면 되겠네? 라는 생각을 할 수 있다.
이제는 모든 컬럼에 인덱싱을 할 경우 생기는 부작용에 대해 알아보자.
읽는 속도는 빠르지만 쓰는 속도는 느려진다.
매번 삽입/삭제를 할 때, 이진트리의 재정렬을 위한 삽입/삭제를 해야만 함(어느정도의 시간이 소요됨)
인덱싱 된 컬럼이 업데이트 된다면 업데이트 속도가 느려진다.
-> 자주 변경되는 컬럼이라면 인덱싱 처리 하지 않는 것이 더 좋다.
테이블에 한 개 이상의 인덱싱이 있다면, 테이블의 자체 크기보다 더 많은 공간이 필요 할 수 있다.
인덱싱이 여러개가 있다면 쿼리를 최적화 하는데 있어 시간이 오래걸릴 수 있다.
따라서 모든 경우에 인덱싱을 처리하는 것이 좋은 것 만은 아니다. 프로젝트의 성격과 데이터의 활용에 따라 인덱싱을 사용하는게 이득일 수도 있고 아닐 수도 있다.
정리가 잘 된 글이네요. 도움이 됐습니다.