Eager loading vs Lazy loading
Lazy Loading은 연관된 데이터들을 실제로 접근하기 전에는 로딩하지 않는다. Lazy loading의 예시를 보자.
users = User.where(status: 'active').joins(:profile)
users.each do |user|
user_date << {
name = user.name
age = user.profile.age
}
end데이터에 접근하기 위해 users를 호출하는 1번의 쿼리를 날리고, 이후 do 루프에서 user.profile.age 구문에 의해 profile에 접근할 때마다 N번의 쿼리를 추가로 날리게된다.
이런 문제를 N+1 Problem라고 한다. 근본적으로 ORM에서 Lazy Loading을 사용할 때 발생되는 문제인 것이다.
Rails는 이런 문제를 해결하기 위해 includes라는 메서드를 제공해준다.
With includes, Active Record ensures that all of the specified associations are loaded using the minimum possible number of queries
자 아래처럼 코드를 수정해보자.
users = User.where(status: 'active').includes(:profile)
users.each do |user|
user_date << {
name = user.name
age = user.profile.age
}위 코드에서는 두 번의 쿼리가 발생한다. users 데이터를 찾을 때 한번, users에 대한 profile을 찾는데 한번. 이러한 로딩 방식을 eager loading이라고 부른다.
그럼 joins가 includes보다 효율적인 경우는 무엇일까? 아래처럼 필터의 역할을 할 경우 효율적이다.
users = User.joins(:profile).where('profile.status = ?', 'active')
users.each do |user|
user_date << {
name = user.name
}
enddo 루프에서 profile의 데이터를 사용하지 않고, profile은 단지 filter의 역할을 하는 것이다.
Last updated
Was this helpful?