RailsでN + 1クエリが発生している箇所でイーガーロードを行なってもN + 1クエリが解消されません。
実行しているメソッドは次の通りです。(ビューとコントローラ側の簡略化した実装を追加しました)
ruby
1followed_users = user.followed_users.select_user_cell.limit(30).order("relationships.id").where("relationships.id > 0").includes(:relationships) 2// ビュー側の実装 3json_user_list = [] 4followed_users.each do |followed_user| 5 user_json = followed_user.as_json 6 user_json[:is_added] = user.bool_following(followed_user) 7 json_user_list << followed_user.as_json 8end 9list = { users: json_user_list } 10// コントローラ側の実装 11render json: list, status: 200 12 13 14
この結果ログに表示されるSQLは次の通りです。
sql
1 User Load (0.5ms) SELECT "users".* FROM "users" INNER JOIN "relationships" ON "users"."id" = "relationships"."followed_id" WHERE "relationships"."follower_id" = $1 AND (relationships.id > 0) ORDER BY relationships.id LIMIT 30 [["follower_id", 58]] 2 Relationship Load (0.4ms) SELECT "relationships".* FROM "relationships" WHERE "relationships"."follower_id" IN (101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98) 3 Relationship Load (0.2ms) SELECT "relationships".* FROM "relationships" WHERE "relationships"."follower_id" = $1 AND "relationships"."followed_id" = $2 LIMIT 1 [["follower_id", 58], ["followed_id", 101]] 4 Relationship Load (0.2ms) SELECT "relationships".* FROM "relationships" WHERE "relationships"."follower_id" = $1 AND "relationships"."followed_id" = $2 LIMIT 1 [["follower_id", 58], ["followed_id", 102]] 5 以下同じようなRelationshipクエリが後28個続き次のエラーが表示 6Unused Eager Loading detected 7 User => [:relationships] 8 Remove from your finder: :includes => [:relationships]
includes(:relationships)を追加したことによりSQLの2行目でN + 1クエリを解消するためのクエリが発行されていますが活用されていないようです。
スキーマ及び関連するモデルクラスの概要は次の通りです。
ruby
1# ユーザモデル 2class User < ActiveRecord::Base 3 # フォロワー、フォロワーの関係 4 has_many :relationships, foreign_key: "follower_id", dependent: :destroy 5 has_many :followed_users, through: :relationships, source: :followed 6 has_many :reverse_relationships, foreign_key: "followed_id", class_name: "Relationship", dependent: :destroy 7 has_many :followers, through: :reverse_relationships, source: :follower 8end 9 10# フォローフォロワーの関係を記録するテーブル 11class Relationship < ActiveRecord::Base 12 belongs_to :follower, class_name: "User" 13 belongs_to :followed, class_name: "User" 14end 15 16create_table "relationships", force: :cascade do |t| 17 t.integer "follower_id" 18 t.integer "followed_id" 19 t.datetime "created_at", null: false 20 t.datetime "updated_at", null: false 21end
環境は次の通りです
Ruby 2.2.3
Rails 4.2.3
何かアドバイスをいただけると助かります。
よろしくお願いします。
回答1件
あなたの回答
tips
プレビュー