본문 바로가기
Spring Framework

[Spring Framework] LazyCollectionOption.EXTRA 으로 SQL 최적화

by 올리브영 2023. 3. 30.
728x90
반응형
 

[Spring Boot] N + 1 Query 문제, default_batch_fetch_size로 해결

Question엔티티 구성은 아래와 같다. @Getter @Setter @Entity public class Question { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; @Column(length = 200) private String subject; @Column(columnDefinition = "TEXT") priva

0live-young.tistory.com

앞에서 배치사이즈를 이용해 최적화를 시켜줬다.

 

하지만 게시물의 답변 개수를 가져올때 한꺼번에 정보를 가져와서 좋지만,

답변의 id, content, create_date 등 쓸데없는 내용들도 가져온다는 문제가 있다.

SELECT a1_0.question_id,
a1_0.id,
a1_0.content,
a1_0.create_date 
FROM answer a1_0 
WHERE a1_0.question_id IN (10, 9, 8, 7, 6, 5, 4, 3, 2, 1);

 

우리에게 필요한 것은 답변의 개수이다.

쿼리 튜닝을 하기위해서 @LazyCollection(LazyCollectionOption.EXTRA)를 추가해준다.

@Getter
@Setter
@Entity
public class Question {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @Column(length = 200)
    private String subject;

    @Column(columnDefinition = "TEXT")
    private String content;

    private LocalDateTime createDate;

    @OneToMany(mappedBy = "question", cascade = CascadeType.REMOVE)
    @LazyCollection(LazyCollectionOption.EXTRA) // 추가
    private List<Answer> answerList;
}

 

그러면 이제 쿼리는 아래와 같이 바뀐다.

SELECT COUNT(id) 
FROM answer 
WHERE question_id = 10;

SELECT COUNT(id) 
FROM answer 
WHERE question_id = 9;

SELECT COUNT(id) 
FROM answer 
WHERE question_id = 8;

SELECT COUNT(id) 
FROM answer 
WHERE question_id = 7;

SELECT COUNT(id) 
FROM answer 
WHERE question_id = 6;

SELECT COUNT(id) 
FROM answer 
WHERE question_id = 5;

SELECT COUNT(id) 
FROM answer 
WHERE question_id = 4;

SELECT COUNT(id) 
FROM answer 
WHERE question_id = 3;

SELECT COUNT(id) 
FROM answer 
WHERE question_id = 2;

SELECT COUNT(id) 
FROM answer 
WHERE question_id = 1;

 

N+1문제가 또 발생하였지만 쓸데없는 정보없이 깔끔하게 쿼리를 날린다.

그리고 함수가 실행될 때 SELECT COUNT를 실행해준다.

 

 

배치사이즈, LazyCollectionOption.EXTRA 둘다 장단점이 있으니 상황에 맞게 적절하게 이용하면 될것 같다.

728x90
반응형