티스토리 뷰

DataBase/MySQL

[MySQL] 인덱스(Index) 란?

Hero_O 2022. 8. 10. 19:06

 

인덱스 ( Index ) 란?

 

 

인덱스란, 위 그림 처럼 일종의 책의 목차로 DB에서 레코드의 주소값을 특정 컬럼들을 기준으로 정렬된 목록들과 매칭시켜 빠르게 레코드를 조회할 수 있도록 하는 것. 인덱스는 이러한 목차를 가진 키와 값을 따로 관리하는 작업을 하는데, 이 때 키가 인덱스로 설정된 칼람이고 이 칼람을 기준으로 정렬하는 작업이 필요하다. 이 때문에 인덱스는 레코드를 쓰는 작업이 있을 때 인덱스가 없을 때와 다르게 추가 작업이 필요해진다. 대신 목차를 통해 읽기 성능을 향상 시키는데 결국 인덱스는 읽기 성능을 향상시키기 위해 쓰기 성능을 일부 포기하는 방식을 의미한다.  다만, 이러한 인덱스의 읽기 방식은 그냥 테이블 전체를 읽어내는 테이블 풀 스캔 방식보다 언제나 빠른 것은 아니다.

 

순차I/O와 랜덤 I/O

순차I/O

순차 I/O는 디스크로 부터 데이터를 읽어 올 때, 디스크의 시작 지점을 찾아 순서대로 읽어오는 방식을 의미한다.

 

랜덤I/O

랜덤 I/O는 디스크로 부터 데이터를 읽어 올 때, 분산 되어있는 데이터들의 위치를 랜덤으로 찾아 읽어 오는 방식을 의미한다.

 

 

 

인덱스의 읽기 방식과 풀 테이블 스캔 방식의 읽기 성능을 얘기하다 갑자기 순차I/O와 랜덤 I/O를 설명한 이유는 풀 테이블 스캔 방식은 순차I/O를 인덱스의 읽기 방식은 랜덤 I/O를 사용하기 때문이다.  기본적으로 순차 I/O는 랜덤 I/O의 비해 많이 빠르다. 상식적으로 생각해도 어지러진 내용보다는 순서대로 있는 내용을 찾기 쉽다. 이 때문에 인덱스를 통한 읽기 방식이 언제나 풀 테이블 스캔 방식보다 빠른 읽기 성능을 보장 하지 않는 것이다. 

 

 

인덱스 스캔 과 풀 테이블 스캔의 읽기 성능

인덱스를 통해 레코드 한 개를 스캔하는 것은 그냥 풀 테이블의 레코드 5~6개의 값을 스캔하는 것과 비슷하다. 이 의미는 읽어야 하는 레코드의 숫자에 따라 전체 테이블을 읽어 내 필요 없는 부분을 버리는 것 보다 인덱스를 통해 읽어내는 것이 느릴 수 도 있음을 의미한다.

평균 적으로 인덱스를 통해 읽어내야 하는 레코드의 숫자가 전체 테이블의 레코드 수의 20% ~ 25%를 넘어가면 풀 테이블 스캔을 통해 데이터를 읽어내는 것이 효율적이다. 

 

💡 위 내용 때문에 보통 통계쿼리를 작성할 때는 인덱스를 사용하지 않는 .

 

B-Tree 인덱스

인덱스를 저장하는 방식으로 가장 많이 사용하는 것은 B-Tree 방식이다. B-Tree의 자세한 설명은 옆에 링크를 통해 확인할 수 있다.

 

 

특징
  • 1개의 페이지에 여러 값을 담아야 페이지간 이동을 줄이거나 B-Tree의 깊이가 줄어들어 성능적이 이득을 얻을 수 있다. 따라서 인덱스의 키 값의 크기는 작을 수록 좋다.
  • 인덱스로 사용하는 칼람의 유니크한 값의 비율이 높아질수록 범위 검색 대상이 줄어들어 성능적 이득을 얻을 수 있다. 
  • 왼쪽에서 오른쪽으로 읽는 것을 정방향, 오른쪽에서 왼쪽으로 읽는 것을 역방향 이라고 하는데, 정방향 스캔의 속도가 29% 정도 더 빠르다.
  • 왼쪽이 작은 값에서 오른쪽 큰 값으로 가는 것을 오름차순 그 반대를 내림차순 이라고 한다.
  • 인덱스의 칼람이 다중으로 되어있을 때 왼쪽 값을 기준으로 오른쪽 값이 정렬되어 있기 때문에, 데이터를 읽어 낼 때 칼람의 순서가 중요하다.

 

 

인덱스 읽기 방식

인덱스 레이지 스캔

  • 인덱스를 활용한 읽기 방식중 가장 빠른 방식중 하나로, 범위로 구분이 가능한 경우에만 가능하다.
  • 인덱스의 시작 지점을 찾고, 시작 지점에서 부터 끝 부분까지를 찾아 디스크에 조회하는 방식.

동작 과정
  1. 인덱스 시작 지점 찾기
  2. 인덱스 시작 지점부터 끝 까지 인덱스 스캔을 진행함.
  3. 그 인덱스 목록들이 가리키는 레코드의 위치들을 랜덤I/O로 모두 조회한다.

 

인덱스 풀 스캔

  • 인덱스의 처음 부터 끝까지 읽어내는 방식으로 읽기 속도가 느리다.

루스 인덱스 스캔

  • Group By 혹은 집계 함수 방식에 사용된다. 필요한 자료만 읽어내고 건너 뛰는 방식이다.
ex) 학년 별 최고 성적의 학생을 검색하라.
index(학년, 성적)로 설정되어 있다면, 학년별로 가장 위에 위치한 값들만 조회하면 되기 때문에 나머지 값은 읽지 않고 스킵할 수 있다.

 

 

 

 

 

 

 

 

Reference

  • Real MySQL 8.0
댓글