티스토리 뷰

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

댓글