MySQL의 기본 -10
랜덤 I/O
랜덤 I/O는 데이터가 디스크 내 임의의 위치에서 읽히거나 써지는 방식을 의미한다. 이러한 비연속적 데이터 접근은 디스크 헤드가 여러 위치로 이동해야 하므로 탐색 시간이 증가해 전반적인 입출력 속도를 저하시킨다. 특히 HDD에서는 회전하는 플래터 위에서 디스크 헤드가 데이터 위치로 물리적으로 이동하고 회전 대기 시간까지 겹쳐져 성능 저하가 심각하다. 반면 SSD는 플래터와 헤드가 없으므로 랜덤 I/O에 상대적으로 강하지만, 여전히 작은 단위의 많은 I/O 요청은 오버헤드를 유발한다.
랜덤 I/O의 대표적인 예로는 B-Tree 인덱스 탐색과 조인(Join) 수행 시 데이터가 여러 위치에서 불규칙하게 읽히는 경우가 있다. 예를 들어, 특정 id 값을 찾기 위해 인덱스를 따라가다 보면 다양한 블록을 랜덤하게 접근해야 하고, 복수 테이블을 조인할 때도 각 테이블 데이터가 디스크의 서로 다른 위치에 분산되어 있어 랜덤 읽기가 발생한다.
MySQL에서는 랜덤 I/O를 최소화하고 성능을 개선하기 위해 여러 기능을 활용한다.
(1) InnoDB의 버퍼 풀은 자주 접근하는 데이터를 메모리 캐시에 저장해 디스크 접근 횟수를 줄인다.
(2) B-Tree 인덱스를 최적화하여 불필요한 인덱스를 제거하고 인덱스 크기를 최소화한다.
(3) 커버링 인덱스는 인덱스만으로 쿼리에 필요한 데이터를 모두 조회할 수 있게 하여 랜덤 I/O를 효과적으로 줄인다.
(4) 조인 최적화를 통해 가능한 한 작은 데이터 집합끼리 조인하도록 설계해 불필요한 랜덤 I/O를 줄이는 전략을 사용한다.
순차 I/O
순차 I/O는 데이터가 디스크 상에서 연속된 위치에서 읽히거나 써지는 방식을 의미한다. 이 방식에서는 디스크 헤드가 한 방향으로만 이동하므로 탐색 시간이 짧아 대량의 데이터를 한 번에 처리하는 데 적합하며, 성능이 뛰어나다. HDD에서 순차 I/O는 특히 큰 성능 차이를 보이며, SSD 환경에서도 여전히 순차 I/O가 랜덤 I/O보다 유리한 점이 있다. 따라서 순차 I/O는 랜덤 I/O보다 훨씬 빠르고 효율적으로 대용량 데이터를 처리할 수 있다.
인덱스와의 관계에서, B-Tree 인덱스는 인덱스 탐색 과정에서 랜덤 I/O가 발생한다. 작은 범위의 데이터를 조회할 때는 유리하지만, 대량 데이터를 조회할 경우 비효율적일 수 있다. 반면 클러스터형 인덱스는 기본키(PK) 순서대로 데이터가 정렬되어 있기 때문에 순차 I/O로 동작한다. 커버링 인덱스를 활용하면 인덱스만으로 데이터를 조회할 수 있어 랜덤 I/O를 줄일 수 있다.
HDD 환경에서 순차 I/O의 특징은 디스크 헤드가 한 번만 이동하면 되고, 한 번의 시스템 콜로 여러 개의 연속된 블록을 처리할 수 있어 물리적 성능을 최대한 활용할 수 있다는 점이다. MySQL에서는 예를 들어, 테이블 전체를 조회하는 Full Table Scan이 대표적인 순차 I/O이며, InnoDB의 클러스터형 인덱스 또한 PK 순서로 데이터가 저장되어 순차 I/O를 발생시킨다.
순차 I/O 성능을 극대화하는 방법으로, 예를 들어 3개의 페이지를 순차적으로 기록할 때 시스템 콜을 한 번만 호출하고 디스크 헤드는 한 번만 이동시키는 방식으로 처리해 성능을 향상시킨다. MySQL 최적화에서는 클러스터형 인덱스 활용, 테이블 정리(OPTIMIZE TABLE), 그리고 파일 정렬 대신 인덱스 정렬(ORDER BY 최적화) 등을 통해 순차 I/O 성능을 강화한다.
순차 I/O 성능을 극대화하는 방법은 디스크의 물리적 특성을 최대한 활용하는 데 초점을 맞춘다. 예를 들어, 3개의 페이지를 순차적으로 기록할 때 각각 별도의 시스템 콜을 발생시키지 않고, 한 번의 시스템 콜로 연속된 페이지들을 묶어 처리하면 오버헤드를 크게 줄일 수 있다. 또한 디스크 헤드가 여러 번 이동하지 않고 한 번만 이동하도록 데이터가 연속적으로 배치되면 탐색 시간을 최소화해 I/O 성능이 비약적으로 향상된다. 이러한 방식은 특히 HDD에서 효과적이며, SSD에서도 순차적으로 데이터를 처리할 때 내부 플래시 메모리의 병렬 처리 효율이 높아져 유사한 성능 이점을 제공한다.
MySQL 환경에서는 이러한 순차 I/O 성능을 강화하기 위해 클러스터형 인덱스(Clustered Index)를 적극 활용한다. 클러스터형 인덱스는 기본키 순서대로 데이터가 저장되어 물리적으로 연속된 공간에 위치하게 하여 순차적 데이터 접근을 용이하게 한다. 또한, OPTIMIZE TABLE 명령을 주기적으로 실행해 테이블을 재정렬하고 조각화(Fragmentation)를 해소함으로써 연속적인 데이터 블록 구성을 유지한다. 아울러, 쿼리 실행 시 파일 정렬(File Sort) 대신 인덱스 정렬(Index Scan)을 활용하여 불필요한 임시 테이블 생성과 디스크 접근을 줄이고, ORDER BY 절을 인덱스 키와 일치시키는 최적화를 적용한다. 이를 통해 데이터 접근 경로가 순차적이며 효율적인 I/O 패턴을 가지도록 설계할 수 있다.
더불어, 쿼리 작성 단계에서도 범위 조건을 활용해 데이터 접근을 연속 구간으로 제한하고, 필요한 컬럼만 조회해 I/O 비용을 줄이는 것이 중요하다. 데이터베이스 서버의 운영 체제와 파일 시스템 또한 대용량 순차 I/O에 최적화된 설정을 적용하는 것이 성능 개선에 도움이 된다. 이러한 종합적인 접근이 결합되어야만 MySQL에서 순차 I/O 성능을 극대화할 수 있다.