私のRailsアプリが非常に多くのSQLステートメントを生成していることにターミナル経由で気づき始めましたが、その多くは必須ではありません。どこかでこれが問題になる可能性があることを読んだことを覚えています。現在、データが大きくなると、アプリの速度が著しく低下します。
たとえば、トラックのあるリリースがあります。アーティストは、トラックとリリースの両方に割り当てることができます。トラックが8つしかないリリースをロードすると、DB内のすべてのトラックを実行して、それらの関係を見つけているようです!?!
たとえば、以下を参照してください。これは非常に小さなサンプルですが、これらのトラックは実際にはリリースに関連付けられていません。DB内のすべてのトラックを通過しています!!
一般的な指針はありますか?
Artist Load (0.6ms) SELECT `artists`.* FROM `artists` INNER JOIN `artists_tracks` ON `artists`.`id` = `artists_tracks`.`artist_id` WHERE `artists_tracks`.`track_id` = 12
Artist Load (0.6ms) SELECT `artists`.* FROM `artists` INNER JOIN `artists_tracks` ON `artists`.`id` = `artists_tracks`.`artist_id` WHERE `artists_tracks`.`track_id` = 19
Artist Load (0.6ms) SELECT `artists`.* FROM `artists` INNER JOIN `artists_tracks` ON `artists`.`id` = `artists_tracks`.`artist_id` WHERE `artists_tracks`.`track_id` = 21
Artist Load (0.9ms) SELECT `artists`.* FROM `artists` INNER JOIN `artists_tracks` ON `artists`.`id` = `artists_tracks`.`artist_id` WHERE `artists_tracks`.`track_id` = 22
Artist Load (0.7ms) SELECT `artists`.* FROM `artists` INNER JOIN `artists_tracks` ON `artists`.`id` = `artists_tracks`.`artist_id` WHERE `artists_tracks`.`track_id` = 23
Artist Load (0.6ms) SELECT `artists`.* FROM `artists` INNER JOIN `artists_tracks` ON `artists`.`id` = `artists_tracks`.`artist_id` WHERE `artists_tracks`.`track_id` = 24
Artist Load (0.9ms) SELECT `artists`.* FROM `artists` INNER JOIN `artists_tracks` ON `artists`.`id` = `artists_tracks`.`artist_id` WHERE `artists_tracks`.`track_id` = 25
Artist Load (1.0ms) SELECT `artists`.* FROM `artists` INNER JOIN `artists_tracks` ON `artists`.`id` = `artists_tracks`.`artist_id` WHERE `artists_tracks`.`track_id` = 26
Artist Load (0.6ms) SELECT `artists`.* FROM `artists` INNER JOIN `artists_tracks` ON `artists`.`id` = `artists_tracks`.`artist_id` WHERE `artists_tracks`.`track_id` = 27
Artist Load (0.9ms) SELECT `artists`.* FROM `artists` INNER JOIN `artists_tracks` ON `artists`.`id` = `artists_tracks`.`artist_id` WHERE `artists_tracks`.`track_id` = 28
Artist Load (0.6ms) SELECT `artists`.* FROM `artists` INNER JOIN `artists_tracks` ON `artists`.`id` = `artists_tracks`.`artist_id` WHERE `artists_tracks`.`track_id` = 29
Artist Load (0.6ms) SELECT `artists`.* FROM `artists` INNER JOIN `artists_tracks` ON `artists`.`id` = `artists_tracks`.`artist_id` WHERE `artists_tracks`.`track_id` = 30
Artist Load (0.6ms) SELECT `artists`.* FROM `artists` INNER JOIN `artists_tracks` ON `artists`.`id` = `artists_tracks`.`artist_id` WHERE `artists_tracks`.`track_id` = 31
関連するモデルは次のとおりです。
class Artist < ActiveRecord::Base
has_many :artist_releases
has_many :releases, :through => :artist_releases
has_many :artists_tracks
has_many :tracks, :through => :artists_tracks
end
class ArtistRelease < ActiveRecord::Base
belongs_to :artist
belongs_to :release
end
class ArtistsTrack < ActiveRecord::Base
belongs_to :artist
belongs_to :release
belongs_to :track
end
class Release < ActiveRecord::Base
has_many :artist_releases
has_many :artists, :through => :artist_releases
accepts_nested_attributes_for :artists, :reject_if => lambda { |a| a[:name].blank? }
accepts_nested_attributes_for :artist_releases
has_many :releases_tracks, :dependent => :destroy
has_many :tracks, :through => :releases_tracks, :order => "releases_tracks.position"
accepts_nested_attributes_for :tracks, :reject_if => lambda { |a| a[:name].blank? }, :allow_destroy => :true
accepts_nested_attributes_for :releases_tracks
end
class ReleasesTrack < ActiveRecord::Base
default_scope :order => 'releases_tracks.position ASC'
acts_as_list :scope => :release_id
belongs_to :release
belongs_to :track
end
class Track < ActiveRecord::Base
has_many :releases_tracks, :dependent => :destroy
has_many :releases, :through => :releases_tracks
has_many :artists_tracks
has_many :artists, :through => :artists_tracks
accepts_nested_attributes_for :artists, :reject_if => lambda { |a| a[:name].blank? }
accepts_nested_attributes_for :artists_tracks
end