Computer-Sience/Database

[Database] N + 1

dev_ss 2023. 4. 12. 00:34

1. N + 1

 Database에서 Query 1번으로 N건의 자료를 가져오고 각 건에 대하여 데이터를 조회하려고 할 때,

각 건마다 Query가 추가로 발생하는 현상

 

이는, 주로 Lazy Loading의 특성을 가진 ORM에서 많이 발생하고 아래 예시를 통해 보게 되면,

 * Lazy Loading : ORM의 객체를 통해 데이터가 처리되는 순간 Query가 발생

Ex : 과일 테이블에서 가격이 1만원 미만인 과일의 이름들의 배열을 얻고자 할 때,
SQL문을 이용하면 Query 1회로 데이터를 얻을 수 있다.

하지만 ORM을 통하면 Code에 for문이 필요하고, 그로 인하여 N + 1 현상이 발생한다.

 

이는 DB에 불필요한 Query를 많이 발생시켜, 성능을 저하시키는 큰 요인이 된다.

 

하지만 대부분의 프레임워크는 해결이 가능하고 방법이 다양하게 존재한다.

 

2. Handle

1) Python - Django : ORM 시 아래 방법을 통해 Eager Loading 한 데이터에서 for문을 적용

  • Select_related : 1:1 또는 N:1의 정참조 외래키 (SQL Query에서 Join)
  • Prefetch_related : N:N 또는 1:N의 역참조 외래키 (Python에서 Join, Query는 2회 발생)

 * Eager Loading : ORM이 적용되는 즉시 Query가 발생

 

 

2) Java - Spring (JPA) : Eager Loading이라도 N+1 문제가 발생할 수 있기에 상황에 맞는 방식을 고려

  • Fetch Join 사용 (Inner Join) : 카디션 곱을 통한 조인이기 때문에 Set이 필요
  • EntityGraph Annotation 이용
  • Batch Size 적용 : N + 1을 해결하는 것보다 최소화에 가까운 개념
반응형