본문 바로가기
데이터베이스

데이터베이스 인덱스, 디스크i/o

by 흰색남자 2022. 11. 11.

데이터베이스에서 가장 큰 cost를 차지하는 것은 디스크i/o이다.

얼마나 적게 디스크를 조금 탐색하느냐 or 디스크를 얼마나 빠르게 탐색하느냐에 따라서 데이터베이스의 성능을 좌우한다.

우리는 디스크를 조금만 탐색하기 위해 인덱스를 만들어서 사용한다.

여기서 궁금한 점이 있다.

인덱스를 사용하면 저장, 업데이트, 삽입 성능이 떨어지는데 왜 사용하지?

성능이 떨어지는 것은 사실이지만, 사용자가 요청하는것을 분석하여 통계를 내보면 케이스마다 다르겠지만, 일반적인 웹 사이트의 경우라면 읽기:나머지의 비율이 8:2 정도이다.

그래서 우리는 다른 0.2 정도의 비율의 성능을 낮추고 인덱스를 사용하여 읽기 성능을 끌어올리는 것이다.

물론 데이터복제하여 읽기전용으로 데이터베이스를 만드는 것도 하나의 방법이다.

 

분산 데이터베이스를 사용하는 것도 빠르게 디스크에서 데이터를 처리하기 위해서 분산된 디스크를 통하여 병렬처리하는것이다.

 

mysql은 여러번 포스팅하였지만 b+tree 구조로 되어있다.

루트, 부모, 자식, 리프노드로 이루어져 있고, 리프노드에 데이터가 저장되는 형식이다.

 

인덱스를 지정하지 않을 경우에는 풀 테이블스켄 즉, 모든 리프노드를 뒤지면서 검색해야한다.

하지만 인덱스를 지정해도 풀테이블 스켄이 일어나는 경우도 있다.

데이터가 적거나, 찾아야할 데이터가 25% 이상이면 풀테이플 스켄이 일어난다.

 

range 스캔은 이상적으로 인덱스를 잘 설정했을때 일어난다.

 

인덱스 스캔은 모든 인덱스를 찾아야해서 range스캔보다는 성능이 떨어진다고 한다. << 

물론 풀테이블 스캔보다는 성능이 좋음. 데이터 크기가 작기때문에.

 

---

인덱스를 걸어야하는 기준.

1. 어디에 조회가 많이 일어나는가?

2. 카디널리티가 높은 컬럼. 유니크한 값이 많은 컬럼.

// 중복도가 낮으면 카디널리티가 높다고 표현하고, 중복도가 높으면 카디널리티가 낮다고 표현합니다.

 

복합 인덱스?

두개 이상의 컬럼을 합쳐서 인덱스를 만듬.

하나의 컬럼으로 만들었을 경우보다 더 적은 데이터 분보를 보여 탐색할 데이터 수가 줄어듬.

결합인덱스, 다중 컬럼 인덱스, 컴포짓 인덱스 등의 동의어가 있음.

 

커버링 인덱스란?

인덱스로 설정한 컬럼만 읽어 쿼리를 모두 처리할 수 있는 인덱스.

>> 그냥 select에서 컬럼 선택하는 것이라 보면 쉬움.

1. 인덱스를 사용하여 처리하는 쿼리 중 가장 큰 부하를 차지하는 부분이란?

인덱스 검색에서 일치하는 키 값의 레코드를 읽는것. 일치하는 키 값의 데이터를 읽기위한 디스크 i/o 발생

n 개 인덱스를 검색할 때 최악의 경우 n 번의 디스크 i/o 소요.

 

쿼리 최적화에서 가장 중요한 것. 디스크 i/o 줄이기.

 

 

 

innodb 세컨더리 인덱스란?

리프 노드에는 실제 레코드 주소가 아닌, 클러스터드 인덱스가 걸린 pk를 주소로 가짐.

예 : 인덱스로 설정한 name, category 와 id(pk)를 모두 활용 가능함.