select를 하는 과정들
innodb에서 데이터를 찾는 방법들
**모든 리프 노드의 레코드 혹은 인덱스들은 논리적 순차 정렬되어있다.
**물리적으로 깨질 수 있지만, 캐싱을 통해 논리적 정렬을 물리적 정렬처럼 효율을 관리할 수 있기 때문에 순차 I/O라고 볼 수 있다.
1. 클러스터링 인덱스 스캔
-> pk를 통해 검색
-> 조건에 인덱스가 갖고있는 정보가 없는 경우 인덱스 스캔 후, 클러스터링 인덱스 스캔이 필수적으로 발생
1-1. 범위가 큰 경우(풀 테이블 스캔)
-> b+tree 구조에서 depth+1 시 랜덤 I/O가 발생한다.
-> 반면, 아예 리프 노드까지 들어가 전체 테이블을 순차 I/O로 탐색하는 방법도 있다.
-> 즉, 범위가 크면 일일이 랜덤 I/O를 발생시키며 찾는 것 보다, 순차 I/O를 발생시키며 찾는 것이 낫다.
1-2. 범위가 작거나, 하나를 찾아야 할 경우(하나를 찾는다는 말은 where pk = 1 같은 것)
-> 랜덤 I/O를 통해 하나하나 찾는다. 범위가 작은 경우 풀 테이블 스캔보다 빠르다.
2. 세컨더리 인덱스 스캔
-> pk가 아닌 다른 컬럼을 인덱스로 지정하고, 이를 b+tree구조로 만든다.
-> where 절이나 join 절 등등에서 인덱스가 조건으로 사용된다면, 세컨더리 인덱스 스캔이 발생
-> 커버링 인덱스: 필요한 데이터를 인덱스 자체에서 가져올 수 있을때->매우 빠름
2-1. 범위가 큰 경우(인덱스 풀 스캔)
-> 테이블 풀 스캔 같이 범위가 매우 큰 경우 순차 I/O를 통해 인덱스를 풀 스캔한다.
2-2. 범위가 적절한 경우(인덱스 레인지 스캔)
-> 범위가 적절한 경우에는 범위의 시작(스타트 부분)을 랜덤I/O로 찾아가 순차I/O로 범위만큼 스캔한다.
2-3. 다중 칼럼 인덱스이고, 두번째 이상의 인덱스까지 조건절에 포함될 때(스킵 스캔, 루스 스캔)
->(age, grade)같은 다중 칼럼 인덱스가 있을때, age로 일단 정렬되고, 값이 같으면 grade로 정렬된다.
-> where age > 3 and grade > 3의 경우
-> age가 1,2,3,4,5,6,7,8,9,10 존재, grade는 각 age 당 12345까지 존재한다고 가정
-> 탐색 과정=> age-grade : 1-1, 1-2, 1-3, (스킵 1-4, 1-5) 2-1, 2-2, 2-3, (스킵 2-4, 2-5)... ..... ..... 이런 느낌으로 스킵하며 탐색
다음은 B+Tree 구조의 특성 상 인덱스를 적용해야 할 만 한 컬럼들을 어떻게 선별하는지 알아봐야할 듯..