매일 10만건 정도 로그가 쌓이는 대용량 테이블의 경우 최소 수백만개 행의 데이터가 조회되기 때문에 성능개선이 필수적이다. (특히 트랜잭션이 몰리는 시간에는 성능저하가 심해져서 로딩 시간이 너무 길어진다.)
이 글은 성능개선을 위한 DB 파티셔닝(Partitioning)에 대한 글이지만 이외에도 성능개선을 위한 방법은 다양하다. 몇 가지 예를 들자면 아래와 같다.
① 쿼리 최적화
모든 열을 선택하는 대신 필요한 열만 검색하고 WHERE 절을 사용하여 적절히 결과를 필터링해야 한다. 굳이 전체 데이터를 조회할 필요가 없다면 MySQL의 LIMIT이나 ORACLE의 rownum을 활용해서 검색할 행 수를 제한하는 것도 효과적이다. (LIMIT도 효과적으로 쓰는 방법이 있는데 나중에 설명하고자 한다.)
② index 사용
index 역시 쿼리 성능을 크게 향상시킬 수 있는 도구이다. index는 별도의 데이터 구조를 생성해서 테이블의 일부 데이터만 포함하므로 필요한 행을 빠르게 검색할 수 있다.
③ 테이블 파티셔닝
테이블을 분할하면 쿼리가 전체 테이블 대신 관련 파티션만 스캔하면 되기 때문에 쿼리 성능을 크게 향상시킬 수 있다. 분할은 날짜 범위나 특정 열 값 등 다양한 기분으로 분할 하는 것 이 가능하다. 이 방법이 내가 선택한 방식이다.
④ 효율적인 join 활용
대용량 테이블을 조회하는 경우 join이 효율적으로 사용되지 않으면 병목 현상이 발생한다. 적절한 join 유형과 join 조건을 사용해야한다.
⑤ 캐싱 사용
캐싱은 자주 액세스하는 데이터를 메모리에 저장시켜 엑세스 시간을 단축시키는 방법이다. 대용량 테이블을 조회할 때 쿼리 결과를 캐시로 저장하여 다음 요청에 대해 새로운 쿼리를 수행하지 않고 저장된 결과를 반환시킴으로 써 성능을 크게 개선시킬 수 있다.
위에 언급한 방법들을 잘 결합해서 활용하면 대용량 테이블을 쿼리할 때 최상의 성능을 얻을 수 있다. 하지만 모든 내용을 다루기엔 내가 너무 귀찮으니 오늘은 DB 파티셔닝에 대해 자세히 정리하고자 한다.
이 글을 보고 있는 사람들은 파티셔닝에 대한 개념보단 예제를 보고 퀵하게 이해하고자하는 목적이 클것으로 생각된다. 개념은 간략히 작성하니 다른 블로그를 참고하기 바란다.
DB 파티셔닝(Partitioning)은 대용량 데이터를 분할하여 관리하는 기술로, 데이터를 작은 조각으로 나누어 여러 개의 물리적인 디스크나 서버에 분산 저장함으로써 데이터를 빠르게 처리하고 관리할 수 있도록 한다.
이제 예제를 통해 전체적인 파티셔닝 흐름을 이해해보자.
파티셔닝을 진행할 테이블 생성
월별 파티셔닝을 위해 인덱스 열은 TIMESTAMP로 지정한다.
CREATE TABLE tbl_product( no BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '상품번호', insertDate TIMESTAMP NOT NULL COMMENT '등록 년월일시간', PRIMARY KEY (no, insertDate), KEY IDX_insertDate (insertDate) )
파티셔닝 등록
inserDate로 월별 파티션을 등록한다.
ALTER TABLE tbl_product PARTITION BY RANGE (UNIX_TIMESTAMP(inserDate)) ( PARTITION p_202301 VALUES LESS THAN (UNIX_TIMESTAMP('2022-12-01 00:00:00')), PARTITION p_202302 VALUES LESS THAN (UNIX_TIMESTAMP('2023-01-01 00:00:00')), PARTITION p_202303 VALUES LESS THAN (UNIX_TIMESTAMP('2023-02-01 00:00:00')), PARTITION p_max VALUES LESS THAN (MAXVALUE) );
파티션에 포함된 데이터 조회
tbl_product의 파티션 p_202301 데이터를 조회한다.
SELECT * FROM tbl_product PARTITION (p_202301);
파티션 수정(추가)
새로운 월 파티션을 추가할 경우.
ALTER TABLE tbl_product ADD PARTITION (PARTITION p_202304 VALUES LESS THAN (UNIX_TIMESTAMP('2023-03-01 00:00:00')));
파티션 삭제
기존 월 파티션을 제거할 경우.
ALTER TABLE tbl_product DROP PARTITION p_202301;
파티션 조회
특정 월에 파티션이 잘 걸려있는지 확인할 경우.
EXPLAIN PARTITIONS SELECT * FROM tbl_product WHERE insertDate BETWEEN '2023-01-11' AND '2023-02-19';
'개발 > DB' 카테고리의 다른 글
[DB] MySQL DB 순번 재정렬 (0) | 2023.04.29 |
---|
댓글