Mysql & Maria/admin

MySQL에서 하지말아야 할 것들

dbavayne 2024. 8. 26. 15:08

Count(*) 함수를 검증 로직에 태우는 것

  • MySQL은 Oracle 처럼 row_num을 저장하지 않기 때문에 카운트 쿼리가 매우매우 느립니다.
  • 특히 개발자 분들은 페이지 네이션 할 때 전체 카운트를 세는걸 많이 하는데, 데이터가 많아지면 결과값 리턴이 엄청 늦어집니다.
  • 검증 로직이 아니더라도, 운영중에 데이터가 많은 테이블에 count(*) 하는건 매우 위험한 일입니다.

- show table status 를 보면 간략 통계 조회 가능

- innodb_stats_persistent 파라미터를 on 하면 통계정보를 디스크에 저장한다 근데 이것도 정확한 total 건수는 아니다

 

 

 

 

Primary Key는 되도록 int 계열 데이터 타입에 Auto Increment를 사용

  • MySQL PK는 기본적으로 클러스터드 인덱스이기 때문에 내림차순에 의한 물리적인 재배열이 일어납니다.
  • 유니크 하다고 해서 순서가 없는 랜덤 값으로 PK가 설정되는 경우, 문자나 숫자의 순서대로 재배열이 일어날 수 있습니다. 따라서 PK로 생성 시점에 따른 정렬이 어려울 수 있고, 데이터 재배열이 자주 일어날 수 있습니다.
  • 물론 성능을 위해 uuid v1의 시퀄셜 데이터를 binary 함수를 이용해 키로 사용하는 방법도 있습니다. 다만 FK로 사용할 경우 바이너리 형식의 데이터는 직관적이지 않고, FK키를 이용해 join 및 조건을 주는 경우,  다수에 의해 동시에 개발과 운영이 되는 환경에서는 적합하지 않을 수 있습니다.

 

복합키(Composite Key)로 PK를 만드는 것

여러 키를 조합해서 유니크 값을 가질때 그 것을 PK로 사용할 수 있지만, 문제가 발생할 수 있습니다.

  • 인덱스 크기 증가: 복합키를 기본 키로 사용할 경우, 인덱스의 크기가 증가하게 됩니다. 이는 데이터베이스의 전체 성능에 영향을 미칠 수 있습니다.
  • 인덱스 검색 비용 증가: 인덱스 검색 시 복합키의 각 구성 요소를 순차적으로 비교해야 하므로, 단일 컬럼 키에 비해 검색 비용이 증가할 수 있습니다.
  • 쿼리 복잡성 증가: 복합키를 사용하면 쿼리를 작성할 때 항상 여러 컬럼을 함께 사용해야 하므로 쿼리가 복잡해질 수 있습니다.
  • 가독성 저하: 여러 컬럼을 조건으로 사용하는 쿼리는 가독성이 떨어지고, 유지보수가 어려워질 수 있습니다.
  • 데이터 중복 가능성: 복합키가 아닌 개별 컬럼에 대해 중복된 값이 허용될 수 있습니다. 이는 데이터 무결성에 영향을 미칠 수 있습니다.
  • 외래 키 참조 복잡성: 다른 테이블에서 복합키를 외래 키로 참조하려면 여러 컬럼을 함께 참조해야 하므로, 외래 키 관계가 복잡해질 수 있습니다.
  • 참조 무결성 유지 어려움: 복합키를 외래 키로 참조하는 경우, 참조 무결성을 유지하는 것이 더 어렵고, 쿼리 작성 시 실수가 발생할 가능성이 높아집니다.
  • 인덱스 순서 중요성: 복합키의 컬럼 순서에 따라 인덱스의 효율성이 달라질 수 있습니다. 잘못된 순서로 설정된 복합키는 성능에 부정적인 영향을 미칠 수 있습니다.

 

물리적 모델에 FK 적용하는 것

ERD를 그리거나 테이블 정의서를 작성할 때는 FK를 표기하나, 실제 데이터 모델에서 FK를 적용하면 문제가 많이 발생합니다.

  • 쓰기 작업의 성능 저하: 외래 키 제약 조건은 삽입, 업데이트, 삭제 작업 시 추가적인 무결성 검사를 요구합니다. 이는 쓰기 작업의 성능을 저하시킬 수 있습니다.
  • 잠금 경합: FK 제약 조건으로 인해 참조 무결성을 유지하기 위해 관련 테이블에 잠금이 발생할 수 있습니다. 이는 동시성 문제를 일으키고, 시스템의 전체 성능을 저하시킬 수 있습니다.
  • 데이터 마이그레이션: 데이터베이스 스키마가 자주 변경되거나, 데이터 마이그레이션 작업이 빈번한 경우 FK 제약 조건은 이러한 작업을 복잡하게 만들 수 있습니다.
  • 데이터 통합: 다양한 소스에서 데이터를 통합하거나, 분산 데이터베이스 환경에서 데이터를 처리할 때 FK 제약 조건은 제약이 될 수 있습니다.
  • 분산 처리의 어려움: 분산 데이터베이스 환경에서는 물리적으로 분리된 노드 간의 FK 제약 조건을 유지하기 어렵습니다. 각 노드가 독립적으로 작동 함으로 참조 무결성을 보장하기 어렵습니다.
  • 어플리케이션에서의 관리: 외래 키 제약 조건을 어플리케이션 레벨에서 관리하면 더 유연하고, 성능 최적화가 가능합니다. 이는 특히 고성능, 고가용성 시스템에서 중요합니다.
  • 복잡한 로직 처리: 일부 복잡한 비즈니스 로직은 데이터베이스의 FK 제약 조건으로 표현하기 어렵습니다. 이러한 경우, 어플리케이션 코드에서 로직을 처리하는 것이 더 적합합니다.
  • 이식성: 여러 종류의 데이터베이스 시스템을 사용하거나, 데이터베이스 시스템을 교체할 계획이 있는 경우, FK 제약 조건을 물리적 모델에서 제외하면 이식성이 높아집니다. 데이터베이스 시스템마다 FK 제약 조건의 구현 방식이나 성능 특성이 다를 수 있기 때문입니다.
  • 개발 및 테스트 편의성: 개발 및 테스트 환경에서는 데이터베이스의 제약 조건을 최소화하여 더 빠르게 테스트 데이터를 생성하고, 다양한 시나리오를 실험해 볼 수 있습니다. FK 제약 조건이 있으면 이러한 작업이 번거로울 수 있습니다.

 

JSON 타입 컬럼 사용시 나타나는 문제점

MySQL8 버전부터는 JSON 컬럼을 지원합니다. 하지만 물론 JSON 처리할 수 있는 다른 DB들과 비교했을 때 MySQL의 JSON 컬럼은 아무런 이점이 없고, 아직까지는 단점 투성 입니다.

  • 파싱 오버헤드: JSON 데이터를 삽입하거나 조회할 때 MySQL은 JSON 문자열을 파싱해야 합니다. 이 과정은 시간이 걸리며 성능에 부정적인 영향을 미칠 수 있습니다.
  • 인덱스 제한: JSON 컬럼 내부의 데이터는 인덱싱이 제한적입니다. MySQL은 JSON 컬럼 자체에는 인덱스를 만들 수 없으며, 특정 키나 값에 대한 인덱싱은 가상 컬럼(generated column)을 사용해야 합니다.
  • 유효성 검증: JSON 컬럼은 구조가 유연하여 스키마 유효성 검증을 수행하지 않습니다. 이로 인해 데이터 일관성이 떨어질 수 있습니다.
  • 데이터 무결성: 잘못된 데이터 형식이나 구조를 가진 JSON 데이터를 삽입하는 것을 방지하기 어렵습니다.
  • 복잡한 쿼리: JSON 데이터를 쿼리하는 구문이 복잡해질 수 있습니다. 특히 중첩된 구조를 다룰 때 쿼리의 가독성과 유지보수성이 떨어집니다.
  • JOIN 제한: JSON 컬럼 내부 데이터를 다른 테이블과 JOIN하는 작업이 어렵습니다.
  • 참조 무결성: JSON 컬럼 내부의 데이터는 외래 키 제약 조건을 통해 참조 무결성을 유지하기 어렵습니다.
  • 데이터 일관성: 서로 다른 레코드 간의 JSON 데이터 일관성을 유지하는 것이 어렵습니다.
  • 저장 공간 비효율성: JSON 데이터는 문자열로 저장되므로, 같은 데이터를 구조화된 형식(예: INT, VARCHAR)으로 저장하는 것보다 더 많은 저장 공간을 차지할 수 있습니다.
  • 메모리 사용 증가: JSON 데이터를 처리할 때 파싱과 관련된 메모리 사용량이 증가할 수 있습니다.
  • 제한된 SQL 기능: JSON 컬럼은 일반적인 SQL 기능(예: 그룹화, 집계 함수)과의 호환성이 떨어질 수 있습니다.
  • 호환성 문제: JSON 데이터를 사용하는 다른 애플리케이션이나 서비스와의 호환성 문제가 발생할 수 있습니다.
  • JSON 컬럼을 사용하고 싶다면 그냥 MongoDB를 사용하는 것을 추천.

 

 

 

출처 

https://rastalion.dev/%ea%b0%9c%eb%b0%9c%ec%9e%90%eb%93%a4%ec%9d%84-%ec%9c%84%ed%95%9c-mysql-%ec%82%ac%ec%9a%a9-%ea%b0%80%ec%9d%b4%eb%93%9c/