물리적 크기를 알아내는 건 DB구조 파악의 첫번째 지름길.

어제 크기와 오늘 크기를 알아내어 증가분을 비교한다.

물리적 크기가 큰데 분산이 안되어 있다면, 어떻게 분산 배치할지 고민해야 한다.


DB 스키마 내에 있는 각 테이블의 물리적 구조 조회하기


select * from information_schema.TABLES

where table_schema = 'DB_NAME';



그 중에서 각 테이블의 물리적 크기 조회하기


SELECT TABLE_NAME AS 'Tables', round(((data_length) / 1024 / 1024), 2) 'Data size(MB)',

round(((index_length) / 1024 / 1024), 2) 'Index size(MB)'

FROM information_schema.TABLES

WHERE table_schema = "DB_NAME"

ORDER BY (data_length + index_length) DESC;


물리적 크기는 full scan time을 결정한다.

1 GB 라면 아무리 SSD 라도 금방 응답하기 힘들다.

물리적인 크기에 따라 query time이 비례해서 느려진다면, 데이터 호출 구조를 개선할 필요가 있다.

index tuning 이 가장 손쉬운 방법이고, Memory DB 도입이 가장 손이 많이 가는 방법이다.

Key-value DB 도입은 중간쯤에 있는데 어쨌든 생각을 많이 해야 한다.


각 테이블의 INDEX 크기를 알아내는 방법


SELECT database_name, table_name, index_name, 

round(stat_value*@@innodb_page_size/1024/1024, 2) size_in_mb

FROM mysql.innodb_index_stats

WHERE database_name = 'DB_NAME' 

AND stat_name = 'size' AND index_name != 'PRIMARY'

ORDER BY 4 DESC;


MySQL 은 Primary Key로 정의된 경우 Index file이 별도로 생성되지 않는다.

반면 Oracle 은 Primary Key 도 Index file 을 별도로 생성한다.

요즘에는 Disk 가 싸서 별 의미가 없는데, 옛날에는 조금 달랐다.

내부적으로 Table 을 관리하는 방식에 조금 차이가 있는 듯.


어떻게 분산할 것인가?

Table partitioning 은 로그성 테이블에는 적합하지 않다.

- insert 는 매일 일어나지만, select, update, delete 가 거의 일어나지 않는 경우

- 이 경우는 file 로 관리할 수 있도록 별도 모듈로 분리시키는 게 맞다.


대신 Master table 처럼 원장형태로 가지고 있어야 하는 경우 partitioning 밖에 대안이 없다.

- 매일 추가되는 row 수는 많다. update, delete 가 종종 일어나고, Join query가 필연적인 경우다.

- 이런 데이터를 DB 밖으로 뺄 경우 Query Function 을 가진 Server module 의 부하를 사전에 계산해야 한다.


Row count는 많은데 물리적 크기가 크지 않다면 조금 나중에 생각해도 된다.

Hadoop은 create 는 많으나 delete, update 가 없는 트랜잭션 처리에 적합하다.

mongodb 는 Join 이 필요하지 않는 경우 적합하다.

즉, Master Table 이 적고 Relation 과 의존성 등이 매우 낮은 경우 적합하다.


MySQL이 지고 mongodb가 이기는 게임이 아니다.

하나로 모든 불편을 이겨내는 소프트웨어는 없다.

개발자라면 적어도 이 소프트웨어가 왜 만들어졌는지 이해하고 그 목적과 취지에 맞게 써보자.

소스코드와 시스템 구조가 훨씬 간결해질 것이다.


FIN.

+ 최신글

+ 많이 본 글