비정규화와 JOIN 최소화
최근 어디선가 꽤 유용해보이는 사이트를 발견하고 내가 작업하고 있는 서버도 쌈@뽕하게 다듬어 보고 싶어서 하나씩 체크해보던 중 ..
Consider denormalizing database schema for read-heavy workloads and reduce JOIN operations.
번역기 돌려보면.. 읽기 작업이 많은 워크로드에 대해서는 데이터베이스 스키마를 비정규화하고 JOIN 작업을 줄이는 것을 고려하라..
무슨 말인지는 아주 대충 얕게는 알겠는데 확실하게 하고 싶어서 일단 gpt씨에게 물어보았다.
Q. read-heavy workload에 대한 데이터베이스 스키마 비정규화를 고려하고 JOIN 작업을 최소화한다는게 뭔가요 ?
gpt씨의 대답을 정리해보면
데이터베이스 스키마 비정규화와 JOIN 작업의 최소화는 read-heavy workload에서 성능을 최적화하는 중요한 전략이다.
성능 개선, 응답 시간 감소, 시스템 확장성을 높이는 데 도움을 준다.
데이터베이스 비정규화
데이터를 중복하여 저장함으로써 데이터베이스의 읽기 성능을 향상시키는 방법
비정규화를 통해 데이터를 한 번의 읽기 작업으로 가져올 수 있도록 테이블 구조를 변경
장점
성능 향상 - 한 번의 쿼리로 필요한 데이터를 가져와 읽기 작업의 속도 향상
쿼리 단순화 - JOIN 연산을 최소화하여 쿼리의 단순화, 최적화를 쉽게 할 수 있음
데이터 접근 시간 감소 - 필요한 데이터가 한 테이블에 모여 있어 접근 시간이 줄어듬
단점
데이터 중복 - 저장 공간이 늘어나며 데이터 일관성을 유지하기 어려워짐
데이터 업데이트 복잡성 증가 - 중복된 데이터를 업데이트할 때 여러 테이블을 수정해야 할 수 있음
JOIN 작업 최소화
JOIN 연산은 여러 테이블의 데이터를 결합하여 필요한 정보를 얻는 작업이기 때문에 비용이 많이 들어 read-heavy workload에서는 피하는 것이 좋음
장점
성능 향상 - JOIN 연산을 최소화하면 쿼리 속도가 빨라지고 데이터베이스 부하가 줄어듬
리소스 절약 - 복잡한 JOIN 연산은 CPU와 메모리를 많이 소모하므로 이를 줄이면 리소스 사용량이 감소함
전략
중복 데이터 저장
자주 조회되는 데이터를 중복 저장하여 쿼리 성능 향상
데이터 덤프 테이블 사용
여러 테이블의 데이터를 한 번에 조회할 수 있는 덤프 테이블을 생성하여 사용
캐싱 활용
데이터베이스 쿼리 결과를 캐싱하여 반복 조회 시 성능 향상. Redis나 Memcached 같은 캐시 솔루션을 사용할 수 있음
읽기 전용 복제본 사용
읽기 전용 데이터베이스 복제본을 사용하여 읽기 성능을 최적화. 이는 특히 트래픽이 많은 시스템에서 유용
인덱스 최적화
적절한 인덱스를 사용하여 조회 성능을 높임. 특히 비정규화된 테이블에 인덱스를 추가하여 성능을 개선할 수 있음
결론
비정규화와 JOIN 최소화는 읽기 작업이 많은 시스템에서 데이터베이스 성능을 최적화하는 효과적인 방법이다. 비정규화를 통해 데이터 접근을 단순화하고 성능을 향상시킬 수 있지만, 데이터 중복과 업데이트 복잡성 증가라는 단점도 고려해야 한다. JOIN 연산을 최소화하여 쿼리 성능을 높이고 시스템의 효율성을 개선할 수 있다. 이러한 전략을 적절히 적용하면 시스템의 응답 속도를 크게 개선하고 사용자의 경험을 향상시킬 수 있다.
여기까지가 gpt씨의 답변
사실 지금까지 작업을 하면서 정규화/비정규화에 대해 생각하면서 스키마를 설계했다기 보다는 적당히 이건 중복되니까 빼고.. 저번 프로젝트에서 이런 경우에는 중복되더라도 여기에 한번 더 저장하는게 편할 거 같고.. 이런식으로 해오고 있었다.
나름 본능적으로(?) 더 나은 방법을 찾아 이러쿵 저러쿵하고 있었던 것 같기는 하다만 이제는 내가 뭘 하고 있는 것인지.. 어떤 이유로 이렇게 하는 것인지 .. 알고 할 수 있게 되었달까..? 그리고 누가 '이 데이터는 왜 여기도 있고 여기도 있어요? 이러면 낭비아닌가요?' 하고 물어보면
이거는요 ~ 읽기 작업이 엄청 자주 일어나는데 데이터를 분리해두면 불러올 때 마다 JOIN을 해야되그등요~? 근데 그러면 비용이 많이 들어서요 ~ ^&^* 그래서 비정규화를 해서 JOIN 연산을 줄였답니다 호호 ~
하고 있어보이게 설명할 수가 있게 되었다.
그리고 분명 정규화/비정규화는 전공시간에도 배운 내용이지만 그때 당시에는 머리만 아프고 머리속에 들어오지도 않았었는데 이렇게 몸으로 부딪히며 배우니 훨씬 이해도 잘되고 좋구만요?
매번 이렇게 하나씩 찾아볼때 마다 느끼는거지만 정답이 없다고 해야하나.. 무조건 정규화가 옳고 비정규화는 좋지 않고 그런게 아니라 상황에 따라 적절히 섞어가며 사용해야한다는 것..
끊임 없이 고민하고 생각해야하고 공부해야할 것 같다.
라고 마무리인 것 처럼 말했지만 끝이 아니다.
gpt씨에게 추가 질문을 했다.
Q. 만약 처음에 비정규화를 고려하지 못하고 데이터베이스를 설계했는데, 막상 사용자들이 늘어나면서 비정규화가 필요하다고 판단이 된 경우에는 어떻게 하면 좋을까요
이에 gpt씨는 비정규화를 효과적으로 적용하는 방법에 대한 단계별 가이드를 보여주었다.
요구사항 분석 및 계획 수립
문제 정의
성능 문제가 발생하는 특정 쿼리 또는 테이블 식별
읽기 성능 향상을 위해 비정규화가 필요한 부분을 명확히 정의
비정규화 전략 수립
어떤 데이터가 중복 저장될지, 어떤 테이블이 비정규화될지 결정
비정규화의 목표와 기대 효과 문서화
비정규화 스키마 설계
비정규화된 테이블 설계
새로운 비정규화된 테이블의 구조 설계
중복 저장될 데이터 필드 정의
데이터 일관성 유지 방안 마련
중복된 데이터를 일관성 있게 업데이트할 수 있는 방법 정의
트리거, 뷰, 애플리케이션 로직을 활용하여 데이터 일관성을 유지할 수 있음
데이터 마이그레이션
테이블 생성 및 데이터 복사
새로운 비정규화된 테이블 생성
기존 데이터를 새로운 테이블로 복사
데이터 검증
데이터가 정확하게 복사되었는지 검증
데이터 무결성 확인
애플리케이션 수정
쿼리 수정
애플리케이션에서 비정규화된 테이블을 사용할 수 있도록 쿼리를 수정
데이터 일관성 로직 추가
새로운 데이터를 삽입하거나 기존 데이터를 업데이트할 때 비정규화된 테이블도 함께 업데이트하도록 애플리케이션 로직을 수정
점진적 전환
점진적 롤아웃
비정규화된 테이블과 새로운 쿼리를 점진적으로 롤아웃하여 시스템의 안정성 유지
일부 사용자에게만 새로운 구조를 적용하여 테스트
모니터링 및 최적화
성능을 모니터링하고 비정규화된 구조가 예상대로 성능을 개선하는지 확인
필요에 따라 추가적인 최적화를 수행
최종 전환 및 유지보수
최종 전환
모든 사용자가 새로운 비정규화된 구조를 사용할 수 있도록 전환
기존의 정규화된 테이블은 유지보수 상태로 전환하거나 필요에 따라 삭제
정기적 검토
비정규화된 테이블과 데이터 일관성 로직을 정기적으로 검토하고 시스템의 변화에 따라 업데이트
데이터베이스 설계 변경은 신중하게 계획하고 점진적으로 적용하여 리스크를 최소화하는 것이 중요하다.
어찌보면 당연한 순서와 내용인데 이렇게까지 단계적으로 수행할 생각은 못했기 때문에 좋은 대화였다고 볼 수 있겠다. 아직 우리 프로젝트에서는 이런 작업을 할 부분이 명확히 보이지는 않는,, 작고 귀여운 단계이기 때문에 앞으로 지켜보면서 개선이 필요할 때 이 글을 다시 펼쳐보아야겠다.