2016-12-13 1 views
1

私は、すべての画像を取得し、現在のユーザーがアップロードした、評価されたお気に入りの画像をフィルタリングするクエリを持っています。しかし、これはより多くの時間を消費しています。以下のクエリを参照し、実行時間を短縮するための最適なクエリを提案してください。Railsのクエリを改善して、リスト内の現在のユーザ項目を拒否する方法は?

@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を使用することで、1つのクエリでこれをすべて実行することもできます。

可能な解決策:

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

@AnjankumarHNあなたがRails 5を使用していて、代わりに外部結合が必要な場合は、 'join'ではなく' left_outer_joins'を使用できます。レールが5未満の場合、sql( 'joins( 'ratings images.id = ratings.image_id')')またはArelで記述する必要があります。 – Kkulikovskis

関連する問題