본문 바로가기

Spring

Spring - DB 조회의 최적화

백엔드를 개발하는 사람이 고민하는 부분 중, 중요한 부분인 데이터베이스에 접근하여 원하는 값을 찾으려 할 때의 성능 최적화가 있습니다. 오늘은 이런 DB 조회할 때의 성능 최적화에 대한 다양한 방법이나 아이디어에 대한 내용을 말해보겠습니다.

 

1. DB 조회 성능 최적화 방법 🔍

1. 적절한 조회방식 선택

데이터를 API가 필요한 조건에 맞춰서 정확히 지정하여 조회하는 것이 효율적입니다. 다음은 여러가지 DB를 조회하는 기술들에 대한 간략한 설명입니다.

  • JPQL/Criteria API: JPA를 활용할 때 효율적인 쿼리 작성으로 필요한 데이터만 조회.
  • Native Query: 복잡한 쿼리나 대량 데이터 처리 시 SQL을 직접 사용하여 최적화.
  • QueryDSL: 동적 쿼리 작성 시 성능과 코드 가독성 모두 확보.

2. 불필요한 데이터 조회 최소화

원하는 데이터를 지정하고 조회를 하려고 해도, 부수적으로 조회될 수 밖에 없는 경우도 있습니다. 이런 부분을 방지하여 성능 최적화를 이룰수 있습니다.

 

  • Lazy Loading 사용: 연관된 엔티티를 필요할 때만 로딩 (@OneToMany, @ManyToOne 등).
  • Projection 사용: DTO나 특정 필드만 가져오는 Projection을 통해 필요한 데이터만 조회.
  • Pagination: 대량 데이터를 처리할 때는 페이징 처리 (Pageable, Page).

특히 QueryDSL 을 사용하여 쿼리 작성시 Projection 기능을 사용하면 특정필드만 골라서 조회가능 하기 때문에 성능을 더 끌어올릴 수 있습니다.

 

3. 캐싱 활용

캐시 메모리에 자주 사용되는 데이터가 들어있게 하는 등의 방법을 통해 DB 까지 조회에 도달하지 않고 값을 불러오는 방법도 있습니다. 이 부분은 `캐싱` 이라는 키워드로 따로 블로그 포스팅을 다뤄볼 예정입니다.

 

  • 1차 캐시: JPA에서 제공하는 기본 캐시를 활용 (영속성 컨텍스트).
  • 2차 캐시: Ehcache, Redis 등을 사용하여 반복 조회 데이터 캐싱.

4. 쿼리 튜닝 및 인덱스 설정

 

  • 조인 최적화: 불필요한 조인을 줄이고 필요한 데이터만 가져오기.
  • 쿼리 단순화: 서브쿼리 대신 조인 사용, 불필요한 조건 제거.
  • 자주 조회되는 컬럼, 검색 조건에 포함되는 컬럼에 인덱스를 설정(단, 과도한 인덱스는 추가적인 쓰기 비용을 초래할 수 있음)

 

2. 인덱싱이랑 무엇인가? 📃

인덱스(Index)는 DB에서 특정 컬럼에 대한 빠른 검색을 위해 사용되는 데이터 구조입니다. 책의 목차처럼 테이블에서 특정 데이터를 빠르게 찾아주는 역할을 합니다.

인덱스 종류

  • Single Column Index: 단일 컬럼 기준의 인덱스.
  • Composite Index: 여러 컬럼 조합으로 생성된 인덱스.
  • Unique Index: 유일성을 보장하는 인덱스.

인덱스 생성 방법

MySQL 예제

CREATE INDEX idx_column_name ON table_name(column_name);

 

 

 

 

JPA 예제(Entity 에 설정)

@Entity
@Table(name = "table_name", indexes = @Index(name = "idx_column_name", columnList = "column_name"))
public class ExampleEntity {
    @Id
    private Long id;
    private String columnName;
}

 

3. 성능 분석 및 최적화 확인 방법🔬

1. 실행 시간 측정

  • SQL 쿼리 실행 시간 측정을 위해 데이터베이스 프로파일러나 로깅 툴 사용
  • Spring Boot 에서 Hibernate 쿼리 로깅(application.properties)
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.generate_statistics=true

 

2. `EXPLAIN` 키워드 사용

  • EXPLAIN 을 쿼리문 앞에 붙이면 쿼리 실행 계획을 확인할 수 있습니다.
  • 실행 계획은 쿼리가 테이블에서 데이터를 검색하는 방식(스캔 방식, 인덱스 사용여부 등)을 보여줍니다.
EXPLAIN SELECT * FROM table_name WHERE column_name = 'value';

 

  • 주요 필드
    • type: 쿼리 수행 방식 (e.g., ALL, index, ref, const 등).
    • key: 사용된 인덱스 이름.
    • rows: 예상 처리 행 수.
    • extra: 추가 정보 (e.g., Using index, Using temporary 등).

3. 쿼리 성능 비교

 

  • 인덱스 추가 전/후로 EXPLAIN 결과에서 rows 값 감소type 개선 확인.
  • 실행 시간을 직접 측정하여 최적화된 쿼리 실행 확인.

 

4. `EXPLAIN` 결과 예시

인덱스가 없는 경우

id: 1
select_type: SIMPLE
table: table_name
type: ALL
possible_keys: NULL
key: NULL
rows: 10000
extra: Using where

 

  • type: ALL -> 풀 테이블 스캔 발생
  • rows: 10,000 -> 모든 행을 검사

인덱스가 있는경우

id: 1
select_type: SIMPLE
table: table_name
type: ref
possible_keys: idx_column_name
key: idx_column_name
rows: 100
extra: Using index
  • type: ref -> 인덱스를 사용하여 효율적 조회
  • rows: 100 -> 인덱스를 통해 대상 데이터만 조회

 

추가적인 팁

 

  • 복합 인덱스를 사용할 경우, 검색 조건의 순서가 인덱스 정의 순서와 일치해야 효과적입니다.
  • 인덱스를 과도하게 생성하면 쓰기 작업 성능이 저하될 수 있으니 꼭 필요한 경우에만 생성하는게 좋습니다.
  • 데이터베이스와 애플리케이션 레벨에서 성능 로그를 분석하여 최적화 지점을 찾아볼 필요가 있습니다.

 

728x90
반응형

'Spring' 카테고리의 다른 글

Spring Framework 와 Spring Boot (1)  (0) 2025.03.30
Spring - Redis의 Pub/Sub 및 WebSocket 구현하기  (4) 2024.12.17
Spring - Redis 적용 실습  (0) 2024.11.26
Spring - 낙관적 락 & 비관적 락  (0) 2024.11.24
Spring - Redis  (0) 2024.11.22