데이터베이스/MySQL

인덱스 스캔 방식

dev_roach 2021. 11. 8. 21:34
728x90

어떤 경우에 인덱스를 이용하는게 좋은지를 판단하기 위해서는 어떻게 인덱스를 이용해서 실제 레코드를 읽어내는지 이해해야 한다.

인덱스를 이용하여 스캔하는 방식에는 대표적으로 3가지 방법이 있다.

인덱스 레인지 스캔

다음 쿼리를 예시로 한번 들어보자

 

mysql> SELECT * FROM employees WHERE first_name BETWEEN 'Ebbe' AND 'Gad';

 

인덱스 레인지 스캔은 위와 같이 검색해야 할 인덱스의 범위가 결정됬을때 사용하는 방식이다.

위와 같이 루트 노드 -> 브랜치 노드 -> 리프노드 를 거쳐서 인덱스를 통해서 스캔해야할 지점을 찾는다.

이처럼 차례대로 쭉 인덱스를 읽어 스캔하는 것을 인덱스 레인지 스캔이라고 한다.

 

다만 대부분 인덱스만 읽어서 끝나지 않는다. 

위와 같은 경우는 인덱스 콜럼만 읽어올 경우 커버링 인덱스로 가능한 것이다.

 

예를 들어 우리가 위 쿼리에서는 'SELECT *' 을 이용하고 있으므로 전체 컬럼에 대한 데이터가 필요하게 된다.

위 데이터를 읽어오기 위해서는 결국 물리 저장소에 랜덤 I/O 가 발생하게 된다.

우리가 저번에도 얘기 했듯이 결국 랜덤 I/O 를 줄이는 것이 쿼리 튜닝이라고 할 수 있다고 얘기했다.

보통 인덱스를 통해 20~25% 의 데이터를 읽어야 한다면, 인덱스를 통한 읽기보다 테이블의 데이터를 직접 읽는 것이 더 효율적인 처리방식이 된다.

 

인덱스 풀 스캔

인덱스 풀 스캔은 인덱스의 처음부터 끝까지 모두 읽는 방식을 인덱스 풀 스캔이라고 한다.

위와 같이 모든 리프노드의 처음부터 끝까지 전부 탐색하는 경우를 말한다.

 

일반적으로 인덱스의 크기는 테이블보다 작으므로 직접 테이블을 처음부터 끝까지 읽는 것 보다 인덱스만 읽는 것이 효율적이다.

근데 하나 명심해야 할 것이 있다. 디스크에 랜덤 I/O 가 발생한다면 인덱스를 써서 풀스캔을 하는 것이 더 효율이 안좋다.

진짜 잘생각해야 한다. 대부분 Index Full Scan 이 좋다고 생각하는데 그건 Index 만 읽을 때다.

한번의 I/O Call 로 모든 데이터를 순차적으로 불러오는게 더 좋을 때가 있다.

루스 인덱스 스캔

루스 인덱스는 간단하게 듬성듬성하게 인덱스를 읽는 것을 의미한다.

루스 인덱스 스캔은 인덱스 레인지 스캔과 비슷하지만, 중간마다 필요치 않은 인덱스 키값은 무시하고 다음으로 넘어가는 형태로 처리한다.

 

예를 들어 아래와 같은 쿼리라고 해보자

 

mysql > SELECT dept_no, MIN(emp_no)

                 FROM dept_emp

                WHERE dep_no BETWEEN 'd002' AND 'd004'

                GROUP BY dept_no;

 

여기서 인덱스는 dept_no + emp_no 라고 가정해보자

그래서 우리가 결국 MIN(emp_no) 를 구하기 위해서는 제일 첫번째 인덱스 컬럼만 읽으면 된다.

왜? 순서대로 정렬되어 있을테니까 인덱스니까!

따라서 옵티마이저는 듬성듬성 읽어도 된다고 판단하게 된다.

728x90

'데이터베이스 > MySQL' 카테고리의 다른 글

[MySQL] ngram parser 를 이용할때 'a' 가 검색이 잘되지 않는 이유  (0) 2022.03.03
MySQL Index  (0) 2021.10.31
MySQL Lock System  (0) 2021.10.25
MySQL 에 쿼리가 들어왔을때?  (0) 2021.10.21
InnoDB 엔진의 특성  (2) 2021.10.12