본문 바로가기

백엔드 개발58

#036. 쿼리개선: insert 성능과 테이블 구조 (Index 정리하기) 개념 테이블을 구성하거나 인덱스를 추가할 때는 이 테이블에 쓰기(INSERT, UPDATE, DELETE) 쿼리가 많은 지 읽기(SELECT) 쿼리가 많은지에 따라 테이블 성격을 구분해야한다. (1) InnoDB 스토리지에서 프라이머리 키(Primary Key)의 역할: Mysql , PostGresql 같이 InnoDB 스토리지 엔진을 사용하는 테이블의 프라이머리 키는 클러스터링 키(인덱스 페이지 위치를 찾을 수 있는 키)이다. 프라이머리 키가 랜덤하게 덤프된 데이터 파일의 경우에는 각 레코드의 프라이머리 키가 너무 다른 값을 가지고 있어서 InnoDB 스토리지 엔진이 레코드를 저장할 때 마다 프라이머리 키의 B-Tree 에서 이곳저곳 랜덤한 위치의 페이지를 메모리로 읽어와야 하기 때문에 처리가 더 느.. 2023. 5. 13.
#035. 쿼리개선 : InnerJoin / OuterJoin 과 인덱스 개념 - join 순서와 인덱스 인덱스 레인지 스캔은 인덱스 탐색과 인덱스 스캔으로 구성되어있다. 일반적으로 인덱스에서 가져와는 건수가 소량이기 때문에 인덱스 스캔 작업은 부하가 작지만 특정 인덱스 키를 찾는 인덱스 탐색 작업은 상대적으로 부하가 높다. 조인 작업에서 드라이빙 테이블을 읽을 때는 탐색을 단 한 번만 수행하고, 이후부터는 스캔만 실행하면 된다. 하지만 드리븐 테이블에서는 인덱스 탐색과 스캔 작업을 드라이빙 테이블에서 읽은 레코드 건수만큼 반복한다. 드라이빙 테이블과 드리븐 테이블이 1:1로 조인되더라도 드리븐 테이블을 읽는 것이 훨씬 더 큰 부하를 차지한다. 따라서 옵티마이저는 항상 드라이빙 테이블이 아니라 드리븐 테이블을 최적으로 읽을 수 있게 실행 계획을 수립한다. inner join에.. 2023. 5. 1.
#034. 쿼리개선: "연산"을 해서 index를 사용하지 못한 쿼리 개선 개념 WHERE 절에 사용되는 비교 조건식의 표현식은 상당히 중요하다. 쿼리가 최적으로 실행되려면 적합한 인덱스와 함께 WHERE 절에 사용되는 비교 조건의 표현식을 적절하게 사용해야한다. 문자열 칼럼이나 숫자 칼럼을 비교할 때는 반드시 그 타입에 맞는 상숫값을 사용할 것을 권장한다. 날짜 값을 비교할 때는 DB 내부적으로 문자열 값을 자동으로 DATETIME 타입의 값으로 변환해서 비교를 수행한다. 이 때 아래와 같이 날짜 타입의 포맷을 변환하는 형태를 포함해 날짜 타입 칼럼의 값을 더하거나 뺴는 함수로 변형한 후 비교하면 인덱스를 사용할 수 없다. // hire_date 타입을 강제로 문자열로 변경해 인덱스를 사용하지 못하는 예시 SELECT COUNT(*) FROM emp WHERE DATE_FOR.. 2023. 4. 25.
#033. 리팩터링: Transaction DB 와 Query DB 분리하기 (Mikro ORM) 개념 Transaction DB 와 Query DB 분리해야하는 이유 트랜젝션은 하나의 논리적인 작업셋으로 COMMIT이 되면 실행을 ROLLBACK이 되면 아무것도 적용되지 않는다. 트랜젝션이 시작되면 DB와 커넥션을 맺게 되므로 트랜젝션이 길어질수록 DB의 여유 스레드는 줄어든다. 어느 순간에는 커넥션을 위해 기다려야 한다. 트랜젝션은 가장 작은 단위로 가져가야 한다. 그리고 이와 같은 커넥션 제한 등의 이유로 조회 DB와 마스터 DB를 분리하는 것이 좋다. 따라서 만약 application에서 다음과 같이 transaction 안에서 조회용 쿼리 코드가 있다면 이를 트랜젝션 바깥으로 빼도록 수정하는 것이 좋다. private async update( id: number, dto: UpdateRequ.. 2023. 4. 21.
#032. GCP 서비스로 개발 환경 배포하기(spring profile + cloudrun + cloudflare) [GCP에 서비스 배포하기] (1) docker image기반으로 cloudrun 실행하기 알파 환경을 구성하고 나서 브랜치 전략을 세우려고 하기 때문에 하나의 도커 이미지로 프로덕션과 알파 환경을 구성했다. [환경 구성] - spring profile 구성하기 각 prod(프로덕션), alpha(알파환경- 개발 환경), local(로컬환경 - 로컬 개발 환경) 용도로 profile을 구성해 환경을 분리해서 빌드할 필요까지 느끼지 못해 아래와 같이 resource 를 한 번에 넣고 빌드했다. - docker 에 실행할 profile 환경 변수 주입하기 cloudrun을 실해할 때 환경변수로 profile을 주입했다. 아래 글 참고 https://www.baeldung.com/spring-boot-dock.. 2023. 4. 12.
#031. 쿼리개선: N*M -> N+M 개선하기 개념 Inner Join이 3개 적용되어 총 4개의 테이블을 연결하던 쿼리의 속도 개선. 아래는 작업한 코드를 약간 변형시킨 코드로, 작가 한 명이 벌어들인 수익의 총 합을 구하는 계산식이다. 각 테이블의 크기는 다음과 같다. books: 7196 carts: 11,387,585 price: 854,891 author: 8044 SELECT a.user_id id, SUM(p.amount) total FROM books b INNER JOIN carts ct ON b.id = ct.book_id AND ct.status = '결제완료' INNER JOIN price p ON p.cart_id = ct.id INNER JOIN author a ON b.id = a.book_id AND a.type = 'm.. 2023. 4. 9.