데이터베이스의 쿼리 성능의 최적화를 위해, 인덱스(Index)
에 대한 깊은 이해는 필수입니다. 인덱스를 본격적으로 다루기전에, 디스크의 I/O 관점에서 왜 랜덤 I/O 와 순차 I/O 를 이해하고 어떻게 쿼리가 튜닝되는것인지를 다루어보고자 합니다.
HDD, SSD
최근 HDD 에서 SSD 로 많이 대중화되며 활용되고 있는 추세이지만, 여전히 데티어 저장 매체는 컴퓨터에서 가장 느린 디스크( Disk) 라는 것은 변함없는 사실입니다. 때문에 데이터베이스의 성능 튜닝은 어떻게 디스크를 I/O 를 줄이느냐가 관건입니다.
초당 처리 횟수를 분석해봤을때, Flash Memory 를 사용하는 SSD 는 HDD 에 비해 약 1000배 가량의 차이를 보이며, 이 떄문에 DBMS 용으로 사용할 서버는 대중적으로 많이 채택하고 있습니다.
성능차이
그런데 디스크의 헤더를 움직이지 않고 한번에 많은 데이터를 읽는 순차 I/O
에서는 SSD 가 HDD 와 성능상 거의 차이가 없긴합니다. 그러나, SSD 는 랜덤 I/O
에서 장점이 두각됩니다. DB 서버에서의 대부분의 I/O 는 작은 데이터를 읽고 쓰는 랜덤 I/O 작업입니다. 어떤 자료에 따르면, SSD 와 HDD 의 초당 트랜잭션 처리수의 차이가 무려 7배가 차이 난다고 합니다.
Random I/O, Sequential I/O
우선 랜덤 I/O 란 데이터를 임의의 위치에서 읽거나 쓰는 작업을 의미하며, 순차 I/O 는 데이터를 연속적인 블록으로 순차적으로 읽거나 쓰는 작업을 의미합니다. 이러한 랜덤 I/O 와 순차 I/O 의 공통점은, HDD 의 플래터(원판) 을 돌려서 읽어야 할 데이터가 저장된 위치가 디스크 헤더를 이동시킨 다음 데이터를 행위를 포함하는 것입니다.
둘의 차이점은 디스크 헤더의 위치 이동횟수
에서 큰 차이를 보입니다. 랜덤 I/O 는 페이지(Page), 즉 데이터를 디스크에 쓰기위해 "매번" 디스크 헤더를 움직여서 쓰고 쓸 위치로 이동시키는 시스템 콜을 호출하는 방식입니다. 반면, 순차 I/O 는 매번 헤더를 이동시킬 필요가 없는 작업이 동반됩니다.
각각 언제, 어떻게 발생하는건데 !?
둘의 발생 상황을 정리해보면 다음과 같습니다.
랜덤 I/O
- 특정 레코드나 데이터 블록을 찾기 위해 인덱스를 탐색하는 경우
- WHERE 절에 조건을 포함한 쿼리를 실행하여 특정 레코드를 찾는 경우
- 임의의 데이터 위치에 대한 갱신 또는 삭제 작업을 수행하는 경우
이처럼 랜덤 I/O는 디스크 헤드가 여러 위치로 이동해야 하므로 비교적 느린 작업입니다. 따라서 랜덤 I/O가 많이 발생하는 경우 성능 저하가 발생할 수 있습니다.
순차 I/O
- 테이블의 모든 레코드를 스캔하는 SELECT 쿼리를 실행하는 경우
- 인덱스의 모든 블록을 읽거나 쓰는 경우
- 대량의 데이터를 정렬하거나 그룹화하는 경우
반면, 순차 I/O는 디스크에서 연속적인 데이터를 읽거나 쓰므로 랜덤 I/O에 비해 더 빠른 작업입니다. 따라서 순차 I/O는 대량의 데이터 액세스에 유리한 특성을 가지고 있습니다.
쿼리 튜닝을 통해 Random I/O 를 최소화하기
데이터베이스 쿼리의 성능을 향상시키기 위해서는 가능한한 순차 I/O를 증가시키고, 랜덤 I/O를 최소화하는 것이 최적의 해결책이 되긴합니다. 그러나, 사실 쿼리를 튜닝해서 랜덤 I/O 를 순차 I/O 로 바꿔서 실행할 방법은 그리 많지 않습니다. 일반적으로 쿼리를 튜닝하는 것은 랜덤 I/O 자체를 줄이는 것이 목적이러고 할 수 있습니다.
여기서 랜덤 I/O 줄인다는 것은, 쿼리를 처리하는데 꼭 필요한 데이터만을 읽고 쓰도록 쿼리를 개선하는 것을 의미합니다.