데이터베이스 Index

갱두·2021년 10월 3일
0

📚 데이터베이스

목록 보기
2/9

인덱스란 무엇? 🤷🏻‍♀️

DBMS도 데이터베이스 테이블의 모든 데이터를 검색해서 원하는 결과를 가져 오려면 시간이 오래 걸린다. 그래서 칼럼의 값과 해당 레코드가 저장된 주소를 키와 값의 쌍으로 인덱스를 만들어 두는 것.

DBMS의 인덱스는 항상 정렬된 상태를 유지하기 때문에 원하는 값을 탐색하는데에는 빠르지만 새로운 값을 추가하거나 삭제, 수정하는 경우에는 속도가 느려짐
결론적으로 DBMS에서 인덱스는 데이터의 저장 성능을 희생하고 그 대신 데이터의 읽기 속도를 높이는 기능
✅ SELECT 쿼리 문의 WHERE 조건절에 사용되는 칼럼이라고 전부 인덱스로 생성하면 데이터의 저장 성능이 떨어지고 인덱스의 크기가 비대해져서 오히려 역효과

Index 자료구조

✔️ 그러면 DBMS는 인덱스를 어떻게 관리?

B+-Tree 인덱스 알고리즘

일반적으로 사용되는 인덱스 알고리즘임
B+-Tree 인덱스는 칼럼의 값을 변형하지 않고 (사실 값의 앞부분만 잘라서 관리) 원래의 값을 이용해 인덱싱하는 알고리즘

Hash 인덱스 알고리즘

칼럼의 값으로 해시 값을 계산해서 인덱싱하는 알고리즘으로 매우 빠른 검색을 지원
하지만 값을 변형해서 인덱싱하기 때문에 특정 문자로 시작하는 값으로 검색을 하는 전방 일치와 같이 값의 일부만으로 검색은 못함
주로 메모리 기반의 데이터베이스에서 많이 사용

✔️ 왜 index를 생성하는데 b-tree를 사용하는가

데이터에 접근하는 시간복잡도가 O(1)인 hash table이 더 효율적일 것 같은데?
SELECT 질의의 조건에는 부등호 연산도 포함이 되는데, hash table을 사용하게 되면 등호 연산이 아니라 부등호 연산의 경우에 문제가 발생함
등호 연산에 특화된 hash table은 데이터베이스의 자료구조로 적합 ❌

Primary Index vs Secondary Index

클러스터드 인덱스

인덱스에서 클러스터드는 비슷한 것들을 묶어서 저장하는 형태로 구현되는데 이는 주로 비슷한 값들을 동시에 조회하는 경우가 많다는 점에서 착안된 것
✔️ 여기서 비슷한 값들은 물리적으로 인접한 장소에 저장되어 있는 데이터들을 뜻함

클러스터드 인덱스는 테이블의 프라이머리 키에 대해세만 적용되는 내용이다.
-> 그래서 클러스터드 인덱스는 테이블 당 한 개만 생성할 수 있음
즉, 프라이머리 키 값이 비슷한 레코드끼리 묶어서 저장하는 것을 클러스터드 인덱스라고 표현
클러스터드 인덱스에서는 프라이머리 키 값에 의해 레코드의 저장 위치가 결정되며 프라이머리 키 값이 변경되면 그 레코드의 물리적인 저장 위치 또한 변경되어야 함. 그렇게 때문에 프라이머리 키를 신중하게 결정하고 클러스터드 인덱스를 사용해야 함.

Composite Index

Composite Index란 인덱스를 생성할 때 두 개 이상의 컬럼을 합쳐서 인덱스를 만드는 것
생성도 중요하지만 인덱스로 설정하는 필드의 순서도 중요하다.
title, author 이 순서로 인덱스를 설정한다면 title을 서치하는 경우, 인덱스를 생성한 효과를 볼 수 있지만, author 만으로 서치하면 인덱스 생성이 소용이 없어짐

따라서 SELECT 질의를 어떻게 할 것인가가 인덱스를 어떻게 생성할 것인가에 대해 많은 영향을 끼침.

Index의 성능과 고려해야할 사항

SELECT 쿼리의 성능을 향상시키는 인덱스는 항상 좋을까?

쿼리 문의 성능을 향상시킨다는데 모든 컬럼에 인덱스를 생성해두면 빨라지지 않을까?

놉🙅🏻‍♀️

이유 1)

INDEX를 생성하게 되면 INSERT, DELETE, UPDATE 쿼리문을 실행할 때 별도의 과정이 추가적으로 발생하기 때문

  • INSERT의 경우 INDEX에 대한 데이터도 추가해야 하므로 성능에 손실
  • DELETE의 경우 INDEX에 존재하는 값은 삭제하지 않고 사용 안한다는 표시로 남게 됨. 즉, row의 수는 그대로인 것
    이게 반복되면 실제 데이터는 10만건인데 데이터가 100만건 있는 결과를 낳을 수도 있음 -> 인덱스는 더 이상 제 역할 ❌
  • UPDATE의 경우는 INSERT + DELETE 의 문제점을 가져옴.
    이전 데이터가 삭제되고 그 자리에 새 데이터가 들어오는 개념이기 때문. 즉, 변경 전 데이터는 삭제되지 않고 insert로 인한 문제도 발생

이유 2)

하지만 더 중요한 것은 컬럼을 이루고 있는 데이터의 형식에 따라서 인덱스의 성능이 악영향을 미칠 수 있기 때문
예시)
이름, 나이, 성별 세 가지의 필드를 갖고 있는 테이블을 예시로 하자
이름은 온갖 경우의 수를 갖고, 나이는 INT, 성별은 남,여 두 가지의 경우만 가짐
-> 이 경우 어떤 컬럼에 대해서 인덱스를 생성하는 것이 효율적일까?
이름에 대해서만 인덱스를 생성하면 효율적이다
10000레코드에 해당하는 테이블에 대해 2000단위로 성별에 인덱스를 생성했다고 가정하면 값의 range가 적은 성별은 인덱스를 읽고 또 한 번 디스크 IO가 발생하기 때문에 그만큼 비효율적임

출처 : https://github.com/JaeYeopHan/Interview_Question_for_Beginner

profile
👩🏻‍💻🔥

0개의 댓글