1

これを呼び出そうとするたびに:

  @ships = Ship.find(:all,
                    :conditions => {:sold => params[:sold]},
                    :order => "ship.id desc")

このモデルから:

class Ship < ActiveRecord::Base
    self.table_name = 'ship'

    self.inheritance_column = :ruby_type
    belongs_to :brand, :class_name => 'Brand', :foreign_key => :brand    
    belongs_to :fuel, :class_name => 'Fuel', :foreign_key => :fuel    
    has_many :ship_pictures, :class_name => 'ShipPicture'
    has_many :reservations, :class_name => 'Reservation'    
end

私はこれらのクエリで終わります:

  Ship Load (0.0ms)  SELECT "ship".* FROM "ship" WHERE "ship"."sold" = 'false' ORDER BY ship.id desc
  Brand Load (0.0ms)  SELECT "brand".* FROM "brand" WHERE "brand"."name" = 'Percedes' LIMIT 1
  Fuel Load (0.0ms)  SELECT "fuel".* FROM "fuel" WHERE "fuel"."name" = 'Air' LIMIT 1
  ShipPicture Load (0.0ms)  SELECT "ship_picture".* FROM "ship_picture" WHERE "ship_picture"."ship_id" = 2
  Brand Load (1.0ms)  SELECT "brand".* FROM "brand" WHERE "brand"."name" = 'Volksship' LIMIT 1
  Fuel Load (1.0ms)  SELECT "fuel".* FROM "fuel" WHERE "fuel"."name" = 'Nuclear Reactor' LIMIT 1
  ShipPicture Load (0.0ms)  SELECT "ship_picture".* FROM "ship_picture" WHERE "ship_picture"."ship_id" = 1

なぜこうなった?私は :include またはそのようなものを呼び出していませんか? ship_pictures に参加して、その参加の最初の結果のみを取得したい。

そして 2 つ目: シンボリックな方法とメソッドの方法のどちらが優れていると考えられますか?

4

1 に答える 1

3

これは、ここでの遅延読み込みではないようです。遅延読み込みが使用されていた場合、次のような SQL を使用してBrand、に対して 3 つのクエリのみが表示されると予想されます。FuelShipPicture

WHERE "ship_picture"."ship_id" IN [1,2]

Shipこれらの関連付けのいずれかを呼び出すモデル内の他のコードはありますか?

上記のファインダーがコントローラーからのものである場合ship.fuel、 、ship.brandまたはship.ship_picturesビューのどこかを呼び出している可能性があります。これが N+1 クエリの通常の原因です。コントローラーからのものでない場合は、クエリの結果に対して実行されている他のコードである可能性が最も高くなります。

于 2012-10-15T20:36:20.670 に答える