2012-04-11 12 views
0

このクエリがうまく実行含まれていますRailsのクエリは上のチョーク

p = PlayersToTeam.select("id").joins(:player).limit(10).order("players.FirstName") 

このクエリは、急停止に来て私のシステム全体が発生します。ここでは

p = PlayersToTeam.select("id").includes(:player).limit(10).order("players.FirstName") 

は、モデルは以下のとおりです。

class PlayersToTeam < ActiveRecord::Base 
    belongs_to :player 
    belongs_to :team 

    accepts_nested_attributes_for :player 
end 

class Player < ActiveRecord::Base 
    has_many :players_to_teams 
    has_many :teams, through: :players_to_teams 
end 

私が知る限り、includesLEFT JOINjoinsになりますn INNER JOIN。コマンドライン上でうまく実行

SELECT players_to_teams.id FROM `players_to_teams` INNER JOIN `players` ON `players`.`id` = `players_to_teams`.`player_id` ORDER BY players.FirstName LIMIT 10 

:問合せは、Railsのからである(joinsのために)吐き出します。

SELECT players_to_teams.id FROM `players_to_teams` LEFT JOIN `players` ON `players`.`id` = `players_to_teams`.`player_id` ORDER BY players.FirstName LIMIT 10 

も十分に実行されます。ちょうど2倍の時間がかかります。

playersplayers_to_teamsレコードを効率的にソートする方法はありますか? playersについてはFirstNameのインデックスがあります。

EDIT

はちゃんと半分も実行するクエリに必要な重い最適化をオンにします。クエリを分割することは、データの再構築やクエリのカスタマイズが不十分な最善の解決策でした。

+1

すべての参加キーにもインデックスがありますか? – DGM

+0

あなたが「酔っぱらいを止める」と言うと、どういうことが起こりますか? –

+0

'screeching halt'は、レールコンソールを使用しているときにターミナルウィンドウが座って、Ctrl + Cキーを押すまで回転します。私は通常それをあきらめる数分前にそれを与えます。 –

答えて

0

また、2(3)のクエリに分割することを検討してください。まず - 参加するとソートしてIDを取得します(内部で2つのクエリが含まれています)

players_to_teams = PlayersToTeam.select("id").joins(:player).limit(10).order("players.FirstName") 

セカンド - プレイヤーが事前にロードされたPlayersToTeamsを取得することを。

players_to_teams = PlayersToTeam.include(:player).where(:id => players_to_teams.map(&:id)) 

その後、プレーヤをロードして初期化した状態で、完全にplayers_to_teamsを初期化します。

0

注意するべき点は、includeはプリロードを行うために2番目のdbアクセスを追加することです。その内容を確認してください(INの文はplayer_idsからplayers_to_teamsまで)。 includeを使用して回避する方法については

、あなたはちょうどあなたがこのようにそれを行うことができ、playersから名前が必要な場合:

PlayersToTeam.select("players_to_teams.id, players.FirstName AS player_name").joins(:player).limit(10).order("players.FirstName")