layout: post title: DB 쿼리에서의 인덱스 사용 categories: [dev] author: 김동현 email: [email protected] date: 2022-04-01 tag:


DB 쿼리에서의 인덱스 활용

4차 산업혁명과 함께 빈번하게 등장하는 단어 중 하나가 바로 빅데이터(Big Data) 입니다. 새삼스런 일도 아니지만 인터넷의 등장 이후 계속해서 축적돼 온 방대한 양의 정보, 사용자의 상호작용 및 패턴 분석에 필요한 로그, 두 세 가지 이상의 정보를 조합하여 가공된 정보 등을 저장하기 위해서 기존의 관계형 DB(RDBMS: Relational database management system)에서 벗어나 MongoDB와 같은 NoSQL, 분산 저장 방식의 Hadoop 등의 기술들이 많이 쓰이고 있습니다만, 여전히 기존 관계형 DB의 중요성은 사라지지 않고 있습니다.

이렇게 많이 쌓인 데이터를 효율적이게 처리하기 위해서는 적절한 인덱스(index) 설정과 함께 인덱스를 활용하여 데이터를 조회할 수 있는 쿼리 작성이 필수적이게 되었습니다.

각 DB마다 엔진의 방식 차이가 있지만, 기본적인 방식은 유사하기 때문에 실행 계획을 살펴가면서 확인해보는 것이 좋습니다. 여기서는 시장 점유율의 대부분을 차지하는 Oracle DB, Mysql 기준으로 설명하도록 하겠습니다.

B-Tree 인덱스

인덱스에 가장 일반적으로 사용되는 알고리즘은 B-Tree(Balanced Tree)입니다. Hash 인덱스도 사용되긴 하지만 일부 혹은 범위 검색이 제한됩니다.

img1.png

인덱스 모식도 예시(출처)

최상위의 루트 노드, 말단의 리프 노드, 중간의 브랜치 노드, 그리고 실제 데이터 부분으로 이루어져 있는데, 실제 데이터는 삽입, 삭제, 수정 등이 반복되기 때문에 정렬되어 있지는 않습니다.

각 노드는 인덱스 키와 프라이머리 키 단위인 페이지로 구성되어 있고, 키는 정렬되어 있기 때문에 이를 이용하여 원하는 데이터를 목차 찾듯이 빠르게 찾을 수 있습니다.

그러나 이진 탐색 트리와 마찬가지로 데이터 조회에는 빠르지만 항상 정렬된 상태를 유지하기 위해 삽입, 삭제 시에는 인덱스가 없는 경우보다 비용이 많이 든다는 점 또한 고려해야 합니다. 또한 인덱스를 찾은 상태에서도 데이터 레코드를 읽어오기 위한 Random I/O가 일어나기 때문에 일반적으로 찾고자 하는 데이터가 전체의 1/4 이상이라면 오히려 인덱스 이용이 비효율적이 될 수도 있습니다.

인덱스 스캔 종류

Index Range Scan

찾아야 할 인덱스 범위가 명확하게 정해졌을 때 사용되는 방식입니다. 해당 인덱스 키를 따라서 데이터를 찾은 뒤 데이터 레코드를 순서대로 읽기만 하면 되기 때문에 효율적인 방식입니다.