데이터베이스 성능 개선 공부 (1)
<현재 문제점>
- 특정 페이지에 들어갈 때 로딩이 오래 걸리는 현상 (다른 팀원이 구현했던 페이지)
- 상품 디테일 페이지에 들어가는데 약 6초가 걸린다
- 페이지에 들어갔을 때 돌아가는 쿼리문이 너무 많고, 심지어 n+1 문제가 발생한다
<해결 방법>
1. 쿼리문 조회를 최소한으로 하기
1) select * 보다는 필요한 컬럼만 포함시키기
2) where절을 명확하게 설정하기
3) 인덱스 활용하기
4) 페이징 처리
5) 무작정 LeftJoin 금지! 적절하게 innerJoin을 활용하자
-> LeftJoin은 오른쪽 테이블에 일치하는 컬럼이 없을 경우 null 값을 가진 컬럼으로 채워져서 데이터가 더 많아질 수 있다
-> InnerJoin은 두 테이블에서 일치하는 결과만 반환하기 때문에 데이터가 더 적을 수 있음
-> 상황에 따라서 적절히 활용하자
2. 뷰와 인덱스를 적절한 상황에 맞춰서 사용해보기
3. 배치로 일괄처리할 것이 있나 생각해보기
-> 관리자 페이지에서 매출같은 건 자정에 한번 실행되게 해도 좋을듯?
-> 상품 등록도 굳이 바로바로 등록하지 않고 한번에 몰아서 등록해도 좋을 듯 하다
<view>
Q. 뷰가 뭐지?
- 뷰는 하나 이상의 테이블에서 데이터를 조회하여 결과를 하나의 '가상의 테이블'처럼 보여주는 객체이다.
Q. 왜 사용할까?
- 복잡한 쿼리를 간소화하여 일종의 '저장된 쿼리'처럼 사용할 수 있다. JOIN이나 서브쿼리 등을 사용하지 않고 간단한 SELECT 문으로 처리할 수 있다.
Q. 성능 개선이 어떻게 되지?
- 뷰 자체는 성능을 개선하는 구성 요소는 아니지만, 뷰를 잘 활용하면 쿼리 성능 최적화에 도움을 줄 수 있다. 예를 들어, 필요한 칼럼만 뷰에 포함시켜 전체 테이블을 스캔하는 것보다 빠른 결과를 얻을 수 있다.
💡 view 활용 방법
1. Join같은 복잡한 쿼리문같은 경우에는 뷰로 만들어서 조회를 한번에 하도록 하기
2. 원래 테이블에서 필요한 데이터 컬럼만 추출해서 뷰로 만들어서 그것만 조회하기
💥 주의사항
1. 뷰가 항상 성능 개선을 해주는 것이 아니기 때문에 전, 후 성능 테스트를 꼭 해봐야한다
2. 뷰 내에서도 조인, 서브쿼리 등이 사용되기 때문에 뷰의 성능에 영향을 줄 수 있다.
<인덱스 DB>
Q. 인덱스가 뭐지?
- 인덱스는 테이블의 특정 열(column)에 대한 데이터 구조를 뜻하는데, 이 구조는 주로 데이터 검색 속도를 향상시키기 위해 사용된다.
Q. 왜 사용할까?
- 인덱스를 사용하면 데이터베이스는 테이블의 모든 행(row)을 차례로 검색하는 대신, 빠르게 원하는 행을 찾을 수 있다.
Q. 성능 개선이 어떻게 되지?
- 쿼리 성능을 크게 향상시킬 수 있지만 인덱스가 너무 많거나 잘못 설정되면 성능을 저하시킬 수도 있으므로 주의가 필요하다.
💡 인덱스 db 활용 방법
1. where절 최적화 : 가장 자주 사용되는 쿼리의 where절에 등장하는 열에 인덱스를 생성한다. 이렇게 하면 해당 열을 기준으로 빠른 검색이 가능해진다
2. order by 최적화 : order by절이 있는 열에 인덱스를 적용하면 정렬 속도가 향상된다
3. 두 테이블을 조인하는 경우에도 조인이 사용되는 열에 인덱스를 적용할 수 있다
4. 복합 인덱스 : 두 개 이상의 열을 하나의 인덱스로 묶어서 복합 인덱스를 생성할 수 있다. 해당 열들이 자주 조회되는 쿼리에 유용하다
💥 주의사항
1. 인덱스는 디스크 공간을 차지하고 DML 작업이 느려질 수 있으므로 꼭 필요한 인덱스만 생성해야 한다
2. 너무 많은 중복 값이 있는 열에 인덱스를 생성하면, 인덱스의 효율이 떨어질 수 있다
🔥 예시
1. 상품 ID(product_id)에 대한 인덱스 생성
CREATE INDEX idx_product_id ON products(product_id);
-> 상품 페이지에서 상품 ID를 기준으로 정보를 빠르게 가져오려면 product_id에 인덱스를 생성하는 것이 유용하다
2. 리뷰 ID(review_id)와 상품 ID(product_id)에 대한 복합 인덱스 생성
CREATE INDEX idx_review_product ON reviews(product_id, review_id);
-> reviews 테이블의 product_id와 review_id를 묶어 복합 인덱스를 생성했는데, 이렇게 하면 해당 열들을 함께 사용하는 쿼리의 성능을 향상시킬 수 있다
<배치>
Q. 배치가 뭐지?
- 배치 처리는 일련의 데이터 처리 작업을 일괄적으로 처리하는 것을 말한다. 시스템이나 사용자의 요청에 즉각적으로 응답할 필요가 없는 작업에서 주로 사용된다
Q. 왜 사용할까?
- 작은 작업을 하나씩 처리하는 것보다 일괄 처리가 효율적일 때가 많다. 이는 CPU와 I/O 리소스를 효율적으로 사용하게 해준다.
Q. 성능 개선이 어떻게 되지?
- 배치 처리를 통해 대량의 데이터를 빠르고 효율적으로 처리할 수 있으므로, 전체적인 시스템 성능을 향상시킬 수 있다.
💡 배치 활용 방법
1. 일, 주, 월 등 정기적으로 반복되는 데이터 업데이트 작업을 배치로 묶어 처리할 수 있다
2. 로그 분석, 통계 생성 등 대량의 데이터를 한번에 처리해야 할 경우에 배치 처리가 유용하다
💥 주의사항
1. 배치 작업은 한번에 많은 양을 처리하기 때문에 문제가 발생했을 때 디버깅이 어려울 수 있다
2. 배치 작업 중 하나가 실패할 경우, 전체 배치 작업을 롤백할지, 아니면 일부만 적용할지 결정해야 한다