티스토리 뷰
N+1 Query Problem
예를 들어 Client 모델에 관계되어 있는 address 모델에서의 postcode를 뽑을 때 아래와 같은 코드를 사용하면,
clients = Client.limit(10)
clients.each do |client|
puts client.address.postcode
end
겉으로는 괜찮아 보이나 11번의 SQL 쿼리를 실행하는 안타까운 점이있다.
Client Load (0.1ms) SELECT * FROM "clients" LIMIT 10
Address Load (0.2ms) SELECT * FROM "address" WHERE "client_id" = 1
Address Load (0.2ms) SELECT * FROM "address" WHERE "client_id" = 2
...
Address Load (0.2ms) SELECT * FROM "address" WHERE "client_id" = 10
이 문제를 좀 더 효율적으로 변경하려면 Model 클래스의 includes 기능을 사용하면 2번의 쿼리로 해결할 수 있다.
clients = Client.includes(:address).limit(10)
clients.each do |client|
puts client.address.postcode
end
이 경우 단 2번의 쿼리만을 이용하여 해결한다.
SELECT * FROM "clients" LIMIT 10
SELECT * FROM "address" WHERE "address.client_id" IN (1,2,3,4,...,10)
참고 : http://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations