개발자 면접에서 자주 나오는 질문이자,
db 속도 개선에서 도움을 주는 기능인 db 인덱스에 대한 글입니다.
index 란?
한글로는 색인 이라는 뜻을 가진 이 기능은
자주 탐색하는 테이블의 칼럼을 정렬하여 별도의 테이블로 만들어서 ,
조회시 해당 별도 테이블을 먼저 조회하게 만드는 기능입니다.
왜 index를 사용하는 것이 db 및 쿼리 튜닝에 큰 상관요소일까요?
먼저 db가 데이터를 조회하는 방식을 이해할 필요가 있습니다.
db는 데이터를 조회할때 데이터 블록 단위로 데이터를 조회합니다.
데이터 블록은 최소 8kb로, db 튜닝에서 가장 중요한 것이 이 데이터 블록의 수를 줄이는 것입니다.
주로 I/O 데이터를 데이터 블록으로써 처리합니다.
db에서 I/O 데이터를 조회하는 방식은 크게 두가지로 나눌수 있는데,
sequential 과 random 방식입니다.
random 방식은 데이터 블록을 무작위로 하나씩 조회하는 방식입니다.
index 없이 데이터를 조회하는 방식으로 흔히 fullscan이라고 불립니다.
sequential 방식은 인덱스를 이용하여 레코드간 논리적 또는 물리적인 순서를 따라 차례대로 읽어 나가는 방식입니다.
예를 들어 User 라는 테이블에 관련 컬럼이 1000개가 있다고 가정합니다.
그중 이름에서 bang이 들어가는 사람을 조회한다고 가정 하면, 인덱스가 없이 조회할 경우의 random 조회 db 프로세스는 아래와 같습니다.
User 테이블에서 1000개의 컬럼의 데이터를 한 블럭씩 조회.
이름에 bang이 들은 데이터를 반환.
이 과정에서 bang을 포함한 튜플이 2개라고 가정하면 우리는 이 2개의 튜플을 구하기 위해 998개의 튜플을 모두 탐색해야 할수도 있습니다.
index 를 통한 sequential 조회의 경우는 아래와 같습니다.
이름 컬럼으로 index 테이블이 생성된 경우 해당 index 테이블에서 bang에 해당하는 튜플 확인.
튜플에 포함된 물리적 주소값 반환하여 해당 튜플값만을 User 테이블에서 조회 및 반환.
ex) 인덱스에서 조회한 데이터 : (bang, 물리적 주소값 1), (bang,물리적 주소값 2) ->
물리적 주소값을 가지고 User에서 조회한 데이터 반환값 : (물리적 주소값 1, 컬럼들etc) , (물리적 주소값 2, 컬럼들etc)
이 과정에서 bang을 포함한 튜플이 2개라고 가정하면 인덱스 테이블의 튜플 2개와 User 테이블의 튜플 2개만을 조회 및 반환합니다.
1번 항목이 진행될때 인덱스 테이블에서는 경로의 출발점을 root node, 끝점을 leaf node, 중간 경로를 branch node라고 지칭하며, root -> branch -> leaf 순으로 인덱스를 탐색합니다.
최악의 경우로 인덱스 없이 조회할 경우 조회해야할 데이터 블럭의 수가 1000 vs 4 입니다.
처음 언급드린 것 처럼 I/O 데이터 블럭의 조회 차이가 이만큼 차이가 나니 성능에서도 차이가 날수밖에 없는 것입니다.
하지만 탐색해야할 데이터 자체가 적은 경우에는, 인덱스 테이블과 목표 테이블 2가지를 봐야하는 sequential 조회의 특성상 더 많은 자원을 사용하기 때문에
테이블에 존재하는 튜플의 양을 확인하여 인덱스 적용여부를 확인해야 합니다.
다음 내용이 궁금하다면?
이미 회원이신가요?
2023년 12월 25일 오후 10:51