티스토리 뷰
데이터 베이스 인덱스에 대하여
인덱스(Index)란?
인덱스는 데이터 베이스 레코드에 빠르게 접근하기 위해서 키와 값(포인터, 주소)의 쌍으로 구성되는 데이터 구조입니다.
데이터베이스를 책이라고 비유한다면 인덱스는 색인(~내용을 찾으려면 ~쪽으로 가세요)과 같다고 할 수 있습니다.
테이블에 많은 데이터가 저장된 경우에 검색을 해서 원하는 결과를 가져오려면 시간이 오래걸리겠죠.
그래서 `칼럼의 값`과 `레코드가 저장된 주소`로 인덱스로 만들어 두는 것입니다.
읽기의 성능에 집중한 기능
DBMS는 인덱스를 항상 정렬된 상태를 유지하기 때문에 데이터를 탐색, 읽어오는데에는 빠르지만
새로운 값을 저장하거나 삭제, 수정하는 경우에는 실행 속도가 느려집니다. ⭐
따라서 인덱스를 추가하는 건 저장 속도를 어디까지 희생할지, 읽기 속도를 얼마나 높일지에 따릅니다.
인덱스의 분류
인덱스는 데이터를 관리하는 방식과 중복 값 허용 여부 등에 따라 여러 가지로 나눠볼 수 있습니다.
1 - 1. 기본키 인덱스 (Primary Key Index) :
- 기본키를 기준으로 생성된 인덱스입니다.
- 대부분 RDBMS에서는 보든 기본키에 대해 자동적으로 기본키 인덱스를 생성합니다.
1 - 2. 보조 인덱스 (Secondary Index) :
- 기본키 이외의 열에 대한 인덱스입니다.
- 보조 인덱스는 개발자가 명시적으로 생성해야 합니다.
2 - 1. 클러스터 인덱스 (Clustered Index) :
- 테이블에서 데이터가 저장된 물리적 순서와 인덱스의 논리적 순서가 일치하는 인덱스입니다. (실제 디스크에 순차적으로 저장)
- 주로 기본키에 대한 인덱스로 사용됩니다.
- 한 테이블당 하나의 클러스터 인덱스만 존재할 수 있습니다.
- 삽입, 갱신, 삭제 작업이 많은 경우에는 인덱스 재조정으로 인한 오버헤드가 발생할 수 있습니다.
2 - 2. 비클러스터 인덱스 (Non-clustered Index) :
- 클러스터 인덱스와 다르게 물리적 순서와 인덱스의 논리적 순서가 일치하지 않는 인덱스입니다.
- 보조 인덱스로 사용됩니다.
- 한 테이블에 여러 비클러스터 인덱스를 생성할 수 있습니다.
3. 고유 인덱스 (Unique Index):
- 중복된 값을 허용하지 않는 열에 대한 인덱스입니다.
- 기본키 인덱스와 유사하지만, 테이블에 기본키가 없는 경우에도 uniqe한 값을 갖는 열에 대해 생성 가능합니다.
- 고유 인덱스는 쿼리 옵티마이저에게 중요한 문제가 됩니다.
동등 조건에 해당하는 값을 찾으면 더 이상 찾지 않아도 된다는 것을 의미하기 때문이죠.
인덱스의 자료구조
인덱스는 다양한 자료구조로 구현할 수 있습니다.
B-트리 (B-Tree) :
- B-트리는 널리 쓰이는 인덱스 자료구조 중 하나입니다.
- B-트리는 이진 트리를 확장한 형태로, 하나의 노드가 가질 수 있는 자식 노드의 최대 숫자가 2보다 큰 트리 구조입니다.
- 일반적으로 칼럼의 값을 변형하지 않고, 원래의 값을 기반으로 인덱싱합니다.
B+트리 (B+Tree) : ⭐
- B+트리는 B-트리의 변형으로, 데이터베이스에서 널리 사용되는 자료구조 중 하나입니다.
- 리프 노드에만 데이터를 저장하고, 연결 리스트로 구성되어 있기에 범위 검색에 더 효율적입니다.
- [DB] 인덱스에서 B+Tree를 사용하는 이유
해시 인덱스 (Hash Index) :
- 해시 인덱스는 해시 함수를 사용하여 키와 해당하는 값을 빠르게 찾을 수 있도록 하는 자료구조입니다.
- 정확한 일치 검색에 굉장히 효과적입니다.
- 하지만 값을 변형해서 인덱스하기 때문에 전방 일치와 같이 값의 일부만으로 검색하고자 할 때에는 사용할 수 없습니다.
- 주로 메모리 내 데이터베이스에서 사용되며, 대용량 데이터베이스에서는 사용이 제한될 수 있습니다.
인덱스가 왜 필요한가?
이어서 인덱스의 하드웨어적인 특성에 대해 조금 작성해 보겠습니다.
이를 이해하면 왜 인덱스 사용시 데이터 액세스 속도가 빨라지는지 알 수 있습니다.
인덱스를 잘 이해하는 것은 쿼리를 최적화와 성능 부하를 줄이는데에 도움이 됩니다.
HDD 와 SSD
HDD, SSD는 보조 기억 장치입니다. RAM, CPU와 함께 컴퓨터의 전체적인 속도를 좌우하는 요소 중 하나죠.
간단히 둘을 비교하면 다음과 같습니다.
HDD(Hard Disk Drive):
- 회전하는 디스크와 이동하는 헤드를 사용하여 데이터를 저장합니다. 상대적으로 느린 데이터 액세스를 제공합니다.
- 내구성이 낮으며 전력 소모 및 발열이 발생합니다.
- 일반적으로 저렴하지만, 느린 속도로 데이터베이스 및 응용 프로그램의 성능이 저하될 수 있습니다.
SSD(Solid State Drive): ⭐
- 전기적인 방식으로 데이터를 저장, 액세스하여 빠른 데이터 액세스를 제공합니다.
- 회전하는 부품이 없으며 내구성이 높고 소음이 없습니다.
- 일반적으로 비싸지만, 빠른 속도와 높은 성능으로 데이터베이스 및 응용 프로그램에서 많이 사용됩니다.
일반적으로 SSD는 HDD보다 약 5배에서 20배 정도 빠른 연산 속도를 제공합니다.
여기서 말하는 연산이라는 게 뭘까요?
순차 I/O(입출력) 와 랜덤 I/O
드라이브(Drive)에서 말하는 연산은 데이터를 읽거나 쓰는 것을 말합니다.
연산의 성능을 측정하는 측정하는 방법은 여러가지가 있지만,
여기서는 순차 I/O와 랜덤 I/O를 이야기 하고자 합니다.
순차 I/O :
- 데이터를 순서대로 연속적으로 읽거나 쓰는 방식을 의미합니다.
- HDD나 SSD와 같은 저장 장치에서 연속된 데이터 블록을 순서대로 읽거나 쓰는 것을 말합니다.
- 순차 I/O는 데이터를 효율적으로 읽고 쓸 수 있으며 HDD, SSD 모두 비슷하게 빠른 속도를 제공합니다.
- HDD도 인접한 데이터를 읽을 때 디스크 헤더를 움직이지 않고 읽어올 수 있기 때문입니다.
랜덤 I/O :
- 임의의 위치에 있는 데이터를 읽거나 쓰는 방식을 의미합니다.
- HDD나 SSD에서 특정 위치에 있는 데이터를 읽거나 쓰는 것이 랜덤 액세스입니다.
- 랜덤 I/O는 순차 I/O보다 오래걸립니다.
- 특히 HDD 경우, 디스크의 헤드가 이동 및 회전해야 하기 때문에 성능이 저하될 수 있습니다.
데이터베이스에서는 순차 I/O보다 랜덤 I/O가 훨씬 더 많이 일어납니다.
따라서 SSD가 더 뛰어난 성능을 보여줄 수 밖에 없는거죠.
정리해보면 다음과 같습니다.
1. 하드웨어 관점에서 SSD가 HDD보다 빠르다.
2. 하지만 대부분의 읽기 작업은 랜덤 I/O 이기 때문에 느린 것은 같다.
3. 따라서 읽기를 최대한 랜덤 I/O 에서 순차 I/O로 할 수 있게 할 방법이 필요한데 이것이 인덱스다! ⭐
인덱스 사용시 주의사항
그럼 인덱스를 많이 사용해야 성능이 좋아지겠네요? 🤔
그건 아닙니다. 오히려 무분별한 인덱스 사용은 오히려 성능을 떨어뜨릴수 있어요.
인덱스가 많으면 각각의 삽입, 갱신, 삭제 쿼리마다 인덱스를 업데이트해야 합니다.
또한, 쿼리 실행 시 여러 인덱스를 고려해야 하기 때문에 쿼리의 실행 시간이 길어질 수 있습니다.
따라서 필요한 인덱스만 생성하는 것이 중요합니다.
인덱스 대상 칼럼
인덱스의 대상이 되는 칼럼의 데이터 형태도 성능에 많은 영향을 미칩니다.
즉, 어떤 데이터의 형식이냐에 따라 인덱스를 만들면 효율적수도, 반대로 비효율적일 수도 있다는 건데요.
`이름`, `성별`, `나이` 세 가지의 필드를 갖고 있는 테이블을 생각해봅시다.
어떤 칼럼을 인덱스로 지정해야 성능 향상에 도움이 될까요?
정답은 이름에 대한 인덱스 입니다. 이름은 나머지 칼럼에 비해 다양한 경우의 수를 가지기 때문이죠.
성별의 경우, 남자와 여자만 존재한다고 가정했을 때 두 가지 경우의 수를 가지게 됩니다.
이는 책에 색인이 두 개밖에 없는 상황과 같습니다.
두꺼운 책에 색인이 2개 밖에 없다면 특정한 내용을 찾는데에 그닥 도움이 되지 않겠죠?
나이는 0살부터 130살 정도라고 가정해볼까요.
성별보다야 다양하지만 수 백만, 수 천만, 억 단위까지도 갈 수 있는 유저를
약 100개로 분류하는 것과 같습니다. 이것도 데이터가 늘어나면 늘어날수록 그리 도움이 되는 방법은 아닐겁니다.
따라서 읽기 성능을 높이려면, 최대한 다양한 경우의 수를 가진 칼럼을 이용해 인덱스를 만들어야 합니다.
인덱스를 읽고 추가적인 디스크 I/O가 일어나지 않게요.
[참고자료]
감사합니다.
공부한 내용을 복습/기록하기 위해 작성한 글이므로 내용에 오류가 있을 수 있습니다.
'DB' 카테고리의 다른 글
[DB] 락(Lock)과 트랜잭션 (0) | 2024.03.09 |
---|---|
[DB] 정규형(Normal form) (0) | 2024.03.08 |
[DB] SQL의 기본 문법 (0) | 2024.03.04 |
[DB] NoSQL과 레디스(Redis) (0) | 2023.12.07 |
[DB] 트랜잭션(Transaction)과 트랜잭션 격리 수준(Isolation Level) (0) | 2023.11.07 |