#해당 내용들은 RealMySQL 책에 기반하고 있습니다
데이터베이스 성능 튜닝 ~ 디스크 I/O 줄이기
-> DB 서버에서는 항상 디스크 장치가 병목 지점
SSD는 데이터 저장용 플래터를 제거하고 플래시 메모리를 장착 -> 원판의 기계적 회전이 사라져 HDD보다 빠름
디스크의 헤더를 움직이지 않고 한번에 많은 데이터를 읽는 순차 I/O에서는 SSD ~ HDD
하지만 랜덤 I/O에서는 SSD가 HDD보다 훨씬 빠름
랜덤 IO vs. 순차 IO
순차 IO는 연속된 페이지를 디스크에 기록하기 위해 1번 system call
랜덤 IO는 매번 새롭게 페이지 넣을 위치 찾느라 n번 system call
즉 쿼리를 튜닝하는 것 = 랜덤 IO를 줄여주는 것
인덱스 레인지 스캔: 데이터를 읽기 위해 랜덤 IO 사용
풀 테이블 스캔: 순차 IO 사용
-> 큰 테이블의 레코드 대부분을 읽을 경우에는 임의로 인덱스 레인지 스캔이 아닌, 풀 테이블을 스캔하도록 구성하기도 함
인덱스
인덱스 : SortedList 같은 느낌
인덱스 분류
프라이머리키와, 프라이머리키를 제외한 모든 인덱스인 보조인덱스
B-Tree 인덱스
보통 B+ Tree, B* Tree 이용 (여기서 B는 Balanced!)
B-Tree: 루트 노드(젤 부모), 리프 노드(젤 자식), 브랜치 노드(루트, 리프 노드 제외한 노드들)
리프 노드에는 실제 데이터 레코드를 찾아가기 위한 주소값을 가지고 있음
데이터 레코드는 insert된 순서대로 저장되는 것이 아님!
레코드를 찾아가기 위한 주소값에 InnoDB의 경우에 는 PK가 담김 (PK에 의해 클러스터링 되어 디스크에 저장되기 때문)
인덱스에 새로운 key가 추가될 때 B-Tree에서 적합한 위치를 찾아 추가됨
삭제될 때에는 레코드를 찾아 삭제 마킹
변경의 경우
검색
인덱스 키 값이 커지면 하나의 인덱스 페이지가 담을 수 있는 인덱스 키 값의 갯수가 작아져서, B-Tree의 깊이가 깊어지고, 디스크로부터 읽어야하는 인덱스 페이지도 많아진다. -> 느려짐
인덱스 페이지를 읽는 것도, disk로 부터 읽는 것으로, 인덱스 페이지를 많이 읽어야하는 부분도 병목이 될 수 있음
그래도 B-Tree의 깊이기 4~5 이상까지 깊어지지는 X
Cardinality
인덱스를 통해 테이블의 레코드를 읽는 것은, 인덱스를 안거치고 레코드를 바로 읽는 것보다 높은 비용이 듦 (4~5배)
인덱스를 통한 데이터 읽기
다중 칼럼 인덱스