2016-12-13 9 views
1

나는 모든 이미지를 가져오고 현재 사용자가 업로드 한 등급 및 즐겨 찾기 이미지를 필터링하는 쿼리를 가지고 있습니다. 그러나 이것은 더 많은 시간을 소비합니다. 아래 쿼리를 참조하고 실행 시간을 줄이기위한 최상의 쿼리를 제안하십시오.레일스 쿼리를 개선하여 목록의 현재 사용자 항목을 거부하는 방법은 무엇입니까?

@images = Image.active_images.order('images_order') 
      .where.not(user_id: current_user.id) 
      .select{|item| item.ratings.where(user_id: current_user.id).count <= 0 } 
      .select{|item| item.favorite_images.where(user_id: current_user.id).count <= 0 } 

답변

4

N + 1 개 검색어를 제거하면 시작할 수 있습니다. http://guides.rubyonrails.org/active_record_querying.html을 참조하십시오.

사전로드 연결을 사용하면 실행 시간이 크게 줄어 듭니다.

AREL 또는 순수 SQL을 사용하여 하나의 쿼리에서이 모든 작업을 수행하는 것이 훨씬 더 강력합니다.

가능한 솔루션 :

Image.active_images.joins(:ratings, :favorite_images) 
      .where.not(user_id: current_user.id) 
      .where.not(ratings: { user_id: current_user.id}) 
      .where.not(favorite_images: { user_id: current_user.id }) 
      .distinct #Joining has_many associations might duplicate the image records in your select, so use distinct 
      .order(:images_order) 
+1

'단지''ratings'을 가지고 있으며, Image'를로드 할 수 있도록 기본적으로'INNER JOIN'을 할 것입니다 joins'는'예에 해당 –

+0

@DeepakMahakale을 favourite_images' –

+0

@AnjankumarHRails 5를 사용하고 있고 외부 조인이 필요하다면 조인 대신'left_outer_joins'를 사용할 수 있습니다. 레일이 5 미만이면 sql ('joins ('ratings images.id = ratings.image_id')') 또는 Arel로 작성해야합니다. – Kkulikovskis