코딩항해기

[리뷰/우아한테크] 데이터베이스 INDEX 본문

IT tech

[리뷰/우아한테크] 데이터베이스 INDEX

miniBcake 2024. 11. 28. 13:15

 

 

 

인덱스

색인 기능을 수행한다. 색인은 쉽게 찾아볼 수 있도록 일정한 순서에 따라 놓은 목록을 의미한다. 인덱스 없이 저장된 데이터는 기준이 없어 select 할 때 모든 데이터를 비교해야하므로 느리지만 데이터가 특정 기준으로 정렬되어 있다면 select를 빠르게 할 수 있다.

즉, 인덱스란 데이터베이스 테이블에 대한 검색 성능을 향상시키는 자료 구조이며 WHERE절 등을 통해 활용된다. 인덱스는 항상 최신의 정렬상태를 유지하며, 인덱스도 하나의 데이터베이스 객체이다. 데이터베이스 크기의 약 10%정도의 저장공간을 필요로 한다.

 

인덱스 알고리즘

Full Table Scan

페이지가 여러 개 있어도 순차적으로 데이터에 접근하는 특징이 있다. 접근 비용이 감소한다. 적용 가능한 인덱스가 없거나, 인덱스의 처리 범위가 넓거나 크기가 작은 테이블에 엑세스하는 경우 사용된다. (인덱스를 적용해도 성능 상 이점이 없다고 여겨질 경우)

페이지
데이터가 저장되는 단위이다. (MySQL 기준 16KB)

 

B-Tree (Balanced-Tree)

이진 탐색 트리에서 균형이 깨졌을 때 장점을 살리지 못하는 단점을 보완하기 위해 나온 구조로, 트리의 높이가 같고, 자식 노드를 2개 이상 가질 수 있으며 기본 데이터베이스 인덱스 구조를 갖는다.

 

루트 페이지, 브랜치 페이지, 리프 페이지로 구성되어 루트와 브랜치는 자식 페이지의 정보를 갖고 리프 페이지는 실제 데이터 페이지(클러스터링 인덱스), 데이터의 주소페이지(논-클러스터링 인덱스)이다.

 

이 구조는 루트 페이지에서 먼저 찾은 뒤 해당하는 하위, 리프 페이지로 넘어가 찾게되는 순서를 지니게 된다.

 

select에서는 검색하는 범위가 줄어 효과적이지만 insert를 할 때는 페이지 용량이 다 차면 빈 페이지를 확보해 문제가 되는 페이지의 데이터를 공평하게 나누어 저장하면서 상위 페이지에 새로운 연결정보가 추가되므로 데이터베이스에 부담이 되는 작업이 생기게 된다. 이를 페이지 분할이라고 하며 DB가 느려지고 성능에 영향을 준다. (페이지에 새로운 데이터를 추가할 여유공간이 없어 페이지에 변화가 발생)

 

delete 시에는 데이터를 실제로 지우지 않고 사용안함 표시를 추가한다. update의 경우 delete와 insert를 순차적으로 수행하게 되며 이 경우에도 delete는 실제로 지워지지 않고 기존 값을 사용안함 표시한다.

 

결과적으로 select에서는 성능이 향상되지만 insert update delete에서는 페이지 분할과 사용안함 표시로 인덱스 조각화가 심해져 성능이 저하된다.

 

이진 탐색 트리 Binary Search Tree
이진 탐색과 연결리스트의 장점이 합쳐져 만들어진 자료구조이다. 균형이 있는 이진 탐색 트리의 경우 검색 시간복잡도는 Big-O(Log n)이며, 균형이 없는 이진 탐색 트리의 경우 최악의 경우 O(n)이다.

 

인덱스 종류

클러스터링 인덱스

클러스터란 무리, 군집의 뜻을 가지고 있으며, 클러스터링은 실제 데이터와 무리를 이루는 것을 의미한다. 즉, 논-클러스터링은 실제 데이터와 무리를 이루지 않는 것을 의미한다. 다시말해 클러스터링 인덱스는 실제 데이터와 같은 무리의 인덱스를 의미한다. 실제 데이터가 정렬된 사전같은 느낌이다. (ㄱㄴㄷ) B-Tree의 리프 페이지가 데이터 페이지와 동일하다.

 

논-클러스터링 인덱스 (보조 인덱스, 세컨더리 인덱스)

논-클러스터링 인덱스는 실제 데이터와 다른 무리의 별도의 인덱스를 의미한다. 실제 데이터 탐색에 도움을 주는 찾아보기 페이지같은 역할을 수행한다. 논-클러스터링 인덱스는 리프 페이지와 데이터 페이지가 다르다. 리프페이지에서는 정렬이 되어있지만 실제 데이터 페이지는 정렬이 되지 않는다. 또한 리프 페이지는 데이터 페이지의 주소를 가지고 있어 데이터를 찾을 때 B-Tree를 이용해 리프 페이지에 있는 데이터 페이지 주소를 찾아 데이터를 탐색한다. 

 

한 테이블에 여러 개 존재할 수 있고, 별도의 인덱스 페이지를 생성하기 때문에 추가 공간이 필요하다. 직접 인덱스 생성 시 기본이 논-클러스터링 인덱스이다.

 

인덱스 자동추가

인덱스는 제약조건에 따라 자동으로 발생되며 PK의 경우 클러스터링 인덱스, unique의 경우 논-클러스터링 인덱스 방식을 사용한다. 만약 unique 제약조건이 not null과 함께 걸릴 경우 클러스터링 인덱스가 된다. 클러스터링 인덱스는 테이블 당 1개만 존재 가능하므로 PK와 unique not null이 함께 있다면 PK가 우선순위를 갖게된다.

 

다수의 인덱스

주소값을 사용하지 않는 이유는 데이터 변경 시 구조 전부를 변경해야하기 때문이다. (클러스터링 인덱스가 적용된 컬럼의 실제 값이 들어감)

 

인덱스 적용 기준

카디널리티

그룹 내 요소의 개수라는 의미를 가지고 있으며, 어떤 컬럼에 인덱스를 적용해야할지 결정할 때 사용된다. 카디널리티가 높을 수록 중복 수치가 낮은 것이기 때문에 카디널리티가 높은 컬럼에 인덱스를 적용하면된다.

 

그 외에도 WHERE절(조건 절이 없다면 인덱스가 사용되지 않기 때문), JOIN절, ORDER BY절에 자주 사용되는 컬럼, insert update delete가 자주 발생하지 않는 걸럼 (성능저하문제), 규모가 작지 않은 테이블일 때 인덱스를 적용하면 좋다.

 

인덱스 사용 시 주의사항

잘 사용되지 않는 인덱스는 성능저하만 유발하므로 삭제한다. 

데이터 중복도가 높은(카디널리티가 낮은) 컬럼은 인덱스 효과가 적다.

자주 사용하더라도 insert, update, delete가 자주 일어나는지 고려해야한다.