데이터베이스 성능 저하의 주요 원인은 대량의 데이터가 하나의 테이블에 집중되고, 이 테이블이 단일 하드웨어 공간에 저장되기 때문이다. 이는 마치 교통량이 많아지면 고속도로가 정체되는 것과 같은 원리이다. 특정 테이블에 중요한 데이터가 몰리면 트랜잭션 처리가 집중되어 성능 저하가 발생할 수 있다. 이를 해결하기 위해 테이블 분할이 필요하다.


하나의 테이블에 대량의 데이터가 존재하면 인덱스 트리 구조가 커져서 효율성이 떨어진다. 이는 디스크 I/O가 많이 발생하여 성능 저하를 초래한다. 인덱스가 크면 조회 성능에도 영향을 미치고, 데이터를 입력/수정/삭제할 때도 트랜잭션 처리 성능이 저하된다.
한 테이블에 많은 칼럼이 있으면 데이터가 디스크의 여러 블록에 분산 저장된다. 이로 인해 데이터를 처리할 때 여러 블록에서 데이터를 읽어야 하므로 디스크 I/O가 증가하여 성능이 저하된다.

로우체이닝은 하나의 데이터 블록에 데이터를 모두 저장할 수 없어 두 개 이상의 블록에 걸쳐 저장되는 현상이다. 이는 데이터를 조회할 때 불필요한 I/O가 발생하여 성능을 저하시킨다.

로우마이그레이션은 데이터 블록에서 수정이 발생하면 수정된 데이터를 해당 블록에 저장하지 못하고 다른 블록의 빈 공간에 저장하는 방식이다. 이로 인해 데이터 조회 시 더 많은 블록에 접근해야 하므로 성능이 저하된다.
테이블 분할은 데이터베이스 성능을 향상시키기 위한 중요한 기법이다. 대량의 데이터가 존재하거나 칼럼 수가 많은 경우, 그리고 로우체이닝과 로우마이그레이션이 발생하는 경우 테이블을 분할하여 성능을 최적화할 수 있다. 적절한 테이블 분할을 통해 트랜잭션의 분산 처리를 유도하고, 디스크 I/O를 줄이며, 인덱스 구조를 효율적으로 관리할 수 있다.

칼럼 수가 많은 테이블에서 발생하는 문제
1. 디스크 I/O 증가: 특정 칼럼을 조회하기 위해 여러 블록을 읽어야 하므로 디스크 I/O가 증가한다.
2. 로우체이닝과 로우마이그레이션: 하나의 로우가 여러 블록에 걸쳐 저장되면서 로우체이닝(Row Chaining)과 로우마이그레이션(Row Migration) 현상이 발생한다. 이는 불필요한 I/O를 유발하여 성능을 저하시킨다.
3. 읽기 성능 저하: 한 번에 많은 칼럼을 조회하는 경우는 드물지만, 많은 칼럼이 존재할 때 특정 칼럼만을 조회해도 성능이 저하된다.

도서정보 테이블에는 전자출판유형에 대한 트랜잭션이 독립적으로 발생이 되는 경우가 많고 대체제품에 대한 유형의 트랜잭션이 독립적으로 발생되는 경우가 많이 있어 1:1 관계로 분리하였다.
해결 방안: 테이블 분리
테이블을 1:1 관계로 분리하면 성능을 향상시킬 수 있다. 예를 들어, 도서정보 테이블을 ‘전자출판유형’과 ‘대체제품유형’이라는 두 개의 테이블로 분리할 수 있다. 각 테이블은 독립적인 트랜잭션이 발생하는 경우가 많기 때문에, 분리된 테이블에서 필요한 칼럼만 접근하여 디스크 I/O를 줄일 수 있다.
해결 예시: 도서정보 테이블의 1:1 분리

이렇게 분리하면, 예를 들어 발행기관명, 수량, 공고일, 발행일을 조회할 때 디스크 I/O가 감소하여 성능이 개선된다.
칼럼 수가 많은 테이블은 성능 저하의 원인이 될 수 있다. 트랜잭션 패턴을 분석하여 테이블을 1:1 관계로 분리함으로써, 불필요한 디스크 I/O를 줄이고 성능을 향상시킬 수 있다. 이는 실전 프로젝트에서도 자주 사용하는 기법이다. 테이블 분리를 통해 로우체이닝과 로우마이그레이션을 줄이고, 트랜잭션 처리 성능을 향상시키는 것이 중요하다.
파티셔닝(Partitioning)은 대용량 데이터를 보다 효율적으로 관리하고 성능을 개선하기 위해 테이블을 작은 단위로 나누는 기술이다. 파티셔닝을 통해 특정 파티션에만 접근하여 데이터를 처리함으로써 디스크 I/O를 줄이고 성능을 최적화 할 수 있다.

RANGE PARTITION은 데이터를 연속적인 범위(Range)로 나누는 방식이다. 특정 열의 값을 기준으로 일정한 범위에 속하는 데이터를 각각의 파티션에 저장한다.
예시: 요금 테이블(PK: 요금일자 + 요금번호)이 1억 2천만 건의 데이터를 가지고 있다고 가정해보자. 요금 데이터를 월 단위로 처리하는 경우가 많다면, 요금일자의 년+월을 기준으로 12개의 파티션으로 나눌 수 있다.

LIST PARTITION은 데이터를 특정 값의 목록(List)으로 나누는 방식이다. 특정 열의 값에 따라 데이터를 미리 정의된 목록으로 분할한다.
예시: 고객 테이블이 1억 건의 데이터를 가지고 있으며, 지점, 사업소, 사업장 등의 코드 값으로 데이터를 나눌 수 있다. 예를 들어, 사업소 코드별로 데이터를 분리하여 LIST PARTITION을 적용할 수 있다.
HASH PARTITION은 해싱 알고리즘을 사용하여 데이터를 분할합니다. 특정 열의 값에 해시 함수를 적용하여 파티션을 결정한다.
파티셔닝은 대용량 데이터를 효율적으로 관리하고 성능을 최적화하기 위한 필수 기술이다. 데이터의 특성과 트랜잭션 패턴에 따라 적절한 파티셔닝 방식을 선택해야 한다.
파티셔닝을 통해 데이터베이스 성능을 최적화하고 관리의 용이성을 높일 수 있다.
테이블에 대한 수평분할/수직분할에 대한 결정은 다음의 4가지 원칙을 적용하면 된다.
용량산정은 어느 테이블에 데이터의 양이 대용량이 되는지 분석하는 것이다. 특정 테이블의 용량이 대용량인 경우 칼럼의 수가 너무 많은 지 확인한다. 칼럼의 수가 많은 경우 트랜잭션의 특성에 따라 테이블을 1:1 형태로 분리할 수 있는지 검증하면 된다. 칼럼의 수가 적지만 데이터용량이 많아 성능저하가 예상이 되는 경우 테이블에 대해 파티셔닝 전략을 고려하도록 한다. 이 때 임의로 파티셔닝할 것인지 데이터가 발생되는 시간에 따라 파티셔닝을 할 것인지를 설명된 기준에 따라 적용하면 된다.