안녕하세요. SQLER의 코난 김대우입니다. 
이번 강좌에서는, 12-1. 인덱스 생성과 관리 - 인덱스(Index) 소개를 진행 하겠습니다.


SQLER에서 진행되는, 챗GPT와 함께 배우는 SQL Server 강좌 목록

 

 

 

TL;DR

인덱스는 데이터를 빠르게 검색하기 위해 사용되는 데이터베이스 기능입니다. 인덱스를 잘 작성하면 빠른 성능을 얻을 수 있고, 데이터가 적을 경우 인덱스의 성능이 제한될 수 있습니다. 

 


인덱스와 성능

인덱스 강좌는 SQL Server의 여러 강좌들 중, 가장 많이 성능에 영향을 줄 수 있는 주제입니다. 또한, 데이터베이스 내부 구조를 충분히 이해해야 하기 때문에 많은 개발자 분들이 어려워하는 주제이기도 합니다. SQLER의 강좌에서는 인덱스를 최대한 풀어서 이해하기 쉽게 적었습니다. 차근차근 강좌를 따라 진행해 보시고, 궁금한 사항은 언제든지 SQLER 질문답변 게시판에 문의주세요.

 

 

인덱스란 무엇인가?

인덱스는 트리구조(계층형)로 이루어져 있는, 실제 페이지 데이터를 포인팅 하는 데이터입니다. SQL Server에서 데이터를 저장하는 최소 단위는 페이지(Page)입니다.


☑️ 챗GPT 활용: 인덱스 트리 구조(Index Tree Structure)에 대해서 알려줘

 

131-1-페이지구조.png

이미지 - SQL Server 페이지 구조


페이지는 8KB 단위로 디스크에 생성되는 저장 구조로, 디스크 입출력 작업은 페이지를 대상으로 실행됩니다. 페이지는 96Byte 크기의 헤더(Header)가 있고, 헤더는 페이지 정보와 페이지 고유번호, 페이지 유형, 페이지 사용가능 공간, 페이지가 할당된 데이터베이스 개체 정보를 저장합니다. 오프셋(Offset)은 페이지 끝에서부터 저장되며, 일종의 포인터로 로우 데이터 시작 위치(페이지 시작부터 얼마나 떨어져 있는지)를 표시합니다.


페이지 8개가 모이면 익스텐트(Extents)가 되며, 페이지들을 효율적으로 관리하기 위해 사용하는 SQL Server 저장 단위입니다.
이 페이지에 실제 로우 데이터가 저장됩니다. 물론 페이지 헤더와 오프셋 정보 역시 페이지에 포함되어 있지만, 강좌에서는 데이터만 있다고 가정하고 인덱스 강좌를 진행하겠습니다.

 

 

많은 개발자 분들이 오해하는 인덱스 관련 FAQ를 먼저 정리합니다.

 

인덱스는 공간을 차지하지 않는다?

아닙니다. 인덱스의 종류에 따라 가변적으로 인덱스 크기가 잡힙니다. 물론 실제 데이터에 비례적인 크기로 공간을 차지합니다. 정확한 인덱스 크기 예측은 어렵지만, 대략적으로 예측은 가능합니다. 중요한 건 인덱스 역시 데이터이며, 공간을 차지한다는 점입니다.

 

인덱스를 만들면 항상 빠르다?

아직 말씀드릴 단계는 아니지만 “잘” 만들어야 빠릅니다. 걱정 마세요. SQLER의 인덱스 강좌를 마치면 인덱스 잘 만드는 방법을 배울 겁니다.

 

데이터가 적어도 인덱스가 유용하다?

아닙니다. 데이터가 많을수록 인덱스는 빠른 검색 속도를 비례적으로 낼 수 있습니다. 디스크 종류와 IO 응답속도에 따라 다르지만, 보통 테이블의 크기가 대략 8 MByte보다 작으면 인덱스가 없는 게 유용할 수 있고, 로우의 크기와 데이터형에 따라 다르지만, 페이지 수가 1천 개 미만이라면, 인덱스가 없는 게 유용할 수 있습니다. 경우에 따라 다르니, 자신의 데이터에서 쿼리 실행계획(Query Execution Plan)을 켜고 직접 체크해 보세요.

 

 

데이터 페이지 구조

우선 다음과 같은 단순한 회원 테이블이 있다고 가정합니다. 

 

회원번호
이름 나이
1 김대우 19
2 손석구 40
3 박은빈 30
4 박서준 34
5 구교환 40
6 송중기 37
7 이정재 50
8 김태리 33
9 한소희 28
10 송혜교 41
11 김혜수 52
12 이하늬 40
13 유연석 39


이 회원 테이블은 회원번호, 이름, 나이 정보를 포함하고 있습니다. 이런 데이터가 실제 SQL Server 데이터 페이지에 어떻게 기록이 되어 있을까요?

 

데이터 페이지 1
1 김대우 19
2 손석구 40
3 박은빈 30

 

데이터 페이지 2
4 박서준 34
5 구교환 40
6 송중기 37
     
데이터 페이지 3
7 이정재 50
8 김태리 33
9 한소희 28
     
데이터 페이지 4
10 송혜교 41
11 김혜수 52
12 이하늬 40
     
데이터 페이지 5
13 유연석 39


내부 데이터 페이지에는 위와 같은 방식으로 저장됩니다. 이때, 회원번호 컬럼의 값 검색 상황을 가정하겠습니다.

 

131-2-인덱스검색.png

이미지 - 인덱스 검색


이렇게 회원번호를 검색하는 상황입니다.


회원번호 1번을 찾으려 한다면? 바로 찾았네요. 1번은 데이터 페이지 1에 있으니 8K Byte의 IO로 데이터를 찾았습니다. 다음으로, 회원번호 7번을 찾으려 한다면? 7번은 데이터 페이지 3에 있네요. 3 * 8K Byte IO로 찾았습니다. 만약, 회원번호 13번을 찾으려 한다면? 데이터 페이지 5에 있으니 40K Byte가 소요됩니다.
만약, 회원수가 늘어나 10만 번 회원을 찾으려 한다면? 상당한 IO가 발생하게 될 것입니다.

 

 

인덱스 구조

다시, 인덱스의 구조와 어떻게 빠른 검색 속도를 제공하는지 살펴보겠습니다. C언어를 배운 분이라면 B트리(B-Tree - Balanced Tree)가 익숙하실 거에요. 데이터 정렬에서 일반적으로 사용되는 B트리 구조로 인덱스가 생성되면 어떨까요? 


(잠시만요! 아래 이미지는 실제 인덱스 구조와 다른 B트리를 구조를 단순화시켜서 이해하기 쉽게 그린 그림입니다. 실제 B트리는 저장 패턴과 탐색 패턴도 알고리즘마다 다릅니다.)

 

131-3-btree.png

이미지 - B트리 구조

 

B트리의 근간은 말 그대로 한쪽으로 치우치지 않고 균형을 유지하는 밸런스 기능입니다. 균형을 유지하면, 복잡도가 높아져도(노드가 많아져도) 일정한 검색 속도를 보장받을 수 있습니다.


☑️ 챗GPT 활용: Balanced Tree 알고리즘에 대해 알려줘

 

 

B트리 탐색

위의 과정과 똑 같이 회원번호를 B트리로 탐색해 볼까요?


- 회원번호 1번을 찾으려 하면? 맨 위의 7을 보니  1 < 7 다음 단계에 4가 있네요. 1 < 4 그러니 4로 가면 되겠지요? 다음 단계 4로 가서 노드를 보니 1이 있습니다. 
- 다음 회원번호 7번을 찾으려면 어떻게 찾을까요? 운이 좋네요. 맨 위에서 찾았어요. 
- 다음 회원번호 13을 보면 한 단계 내려가 바로 13을 찾았습니다.  


페이지 데이터가 증가해 함께 B트리도 깊이가 여러 단계 늘어난다고 가정해 보세요. 데이터가 늘어나도, 인덱스는 B트리 구조를 유지하며 깊이가 추가되지만 깊이만큼 분산되며 검색 속도도 빠르게 유지됩니다. 인덱스가 없는 경우, 맨 위부터 모든 페이지 로우 데이터를 스캔할 때보다(이 과정을 풀 스캔-Full scan이라고 부릅니다) 훨씬 더 적은 IO로 원하는 데이터를 찾을 수 있습니다.

 

 

B트리 구조

여기서 B트리의 주요 키워드를 짧게 살펴보겠습니다.

131-4-B트리구조상세.png

이미지 - B tree 상세 구조

 

최상위 노드를 Root 레벨이라고 부릅니다. 위의 B트리 구조 이미지는 중간 레벨이 하나뿐이지만 B트리 데이터가 많아질수록 중간 레벨은 계속 많아집니다. 이 중간 레벨들을 Non-Leaf 레벨, 또는 중간레벨(Intermediate Level)이라고 부르기도 합니다. 끝으로 최하위의 레벨은 Leaf 레벨이라고 부릅니다. 한글로는 각각 루트 수준(노드) / 중간 수준(노드) / 리프 수준(노드)이라고 부릅니다. 


인덱스에 대해 공부하다 보면, B트리 구조와 용어가 자주 나옵니다. 이 정도만 알아두어도, 이후 인덱스를 공부하면서 만나는 설명에 긴장하지 않을 겁니다.


기본적인 인덱스의 구조에 대해 간략히 소개해 드렸습니다. 다음 강좌에서는 실제 데이터와 SQL 구문으로 인덱스를 만들고 사용해 보겠습니다.
 

 

SQL 강좌 책 구매

강좌가 도움이 되셨다면, 책으로 구매 가능합니다. 책 판매 수익금은 전액 코딩 교육 사회공헌 활동에 기부되며, 아래 링크에서 구매하시면 더 많은 금액이 기부됩니다. 

 

책구매 링크: 챗GPT와 함께하는 마이크로소프트 SQL Server 2022 

책구매링크.png

No. Subject Author Date Views
Notice SQL강좌: 챗GPT와 함께 배우는 SQL Server 무료 강좌 목차와 소개 (2023년 9월 업데이트) 코난(김대우) 2023.08.18 21979
Notice Python 무료 강좌 - 기초, 중급, 머신러닝(2023년 6월 업데이트) 코난(김대우) 2021.01.01 12251
» SQL강좌: 12-1. 인덱스 생성과 관리 - 인덱스(Index) 소개 file 코난(김대우) 2023.08.18 61
2293 SQL강좌: 11-8. 관계형 데이터베이스 이해 - 데이터베이스 구현 코난(김대우) 2023.08.18 24
2292 SQL강좌: 11-7. 관계형 데이터베이스 이해 - 데이터베이스 물리적 설계 코난(김대우) 2023.08.18 23
2291 SQL강좌: 11-6. 관계형 데이터베이스 이해 - 데이터베이스 논리적 설계 코난(김대우) 2023.08.18 23
2290 SQL강좌: 11-5. 관계형 데이터베이스 이해 - 데이터베이스 설계 요구사항(Requirements) 분석과 개념적 설계 코난(김대우) 2023.08.18 20
2289 SQL강좌: 11-4. 관계형 데이터베이스 이해 - 데이터베이스 설계 목표와 고려사항 코난(김대우) 2023.08.18 16
2288 SQL강좌: 11-3. 관계형 데이터베이스 이해 - 데이터베이스 설계 단계 file 코난(김대우) 2023.08.18 19
2287 SQL강좌: 11-2. 관계형 데이터베이스 이해 - 데이터베이스 생명주기 file 코난(김대우) 2023.08.18 24
2286 SQL강좌: 11-1. 관계형 데이터베이스 이해 - 관계형 모델 코난(김대우) 2023.08.18 33
2285 SQL강좌: 10-4. T-SQL 프로그래밍 - 공통 테이블 식(CTE-Common Table Expression) 코난(김대우) 2023.08.18 47
2284 SQL강좌: 10-3. T-SQL 프로그래밍 - 변수, 조건문(IF-ELSE), 반복문(WHILE), CASE 표현식 코난(김대우) 2023.08.18 27
2283 SQL강좌: 10-2. T-SQL 프로그래밍 - 일괄처리(Batch) 코난(김대우) 2023.08.18 32
2282 SQL강좌: 10-1. T-SQL 프로그래밍 - 소개 코난(김대우) 2023.08.18 21
2281 SQL강좌: 9-3. 커서 - 현업에서 커서 사용 및 주의사항 코난(김대우) 2023.08.18 49
2280 SQL강좌: 9-2. 커서 - 커서 구문 코난(김대우) 2023.08.18 23
2279 SQL강좌: 9-1. 커서(CURSOR) - 커서 소개 코난(김대우) 2023.08.18 40
2278 SQL강좌: 8-7. 저장 프로시저 - 프로시저 캐시와 RECOMPILE 코난(김대우) 2023.08.18 40
2277 SQL강좌: 8-6. 저장 프로시저 - 종속성(Dependency) 확인 코난(김대우) 2023.08.18 44
2276 SQL강좌: 8-5. 저장 프로시저 - OUTPUT 파라미터 코난(김대우) 2023.08.18 44
2275 SQL강좌: 8-4. 저장 프로시저 - 동적 SQL(Dynamic SQL)과 SQL 주입(Injection) 공격 코난(김대우) 2023.08.18 54





XE Login