まず、デカルト積ではなく、明示的な JOIN 構文を使用してクエリを作成します。おそらく、最新のオプティマイザーのパフォーマンスに関しては何の違いもありませんが、JOIN がどのように機能するかに関する情報がプログラマーにとってよりアクセスしやすくなります。
SELECT Player.Name, Game.Date
FROM Player
INNER JOIN Game ON Game.WinnerPlayerID = Player.PlayerID
WHERE Game.WinnerFrags > Game.TotalFrags/2
ORDER BY Player.Name
これにより、ゲーム内の他のすべてのプレーヤーを合わせたよりも多くのフラグを獲得したすべてのプレーヤーと、ゲームの日付が名前でソートされます。いずれにせよオプティマイザは JOIN の一部としてフィルタリングを実行する可能性が高いため、両方の条件を JOIN に配置しても、おそらくパフォーマンスには影響しません。ただし、LEFT JOIN にとっては問題になり始めます。今週の上位 10 人のプレイヤーが、上記の差で勝ったゲームの数を探しているとしましょう。それらのいくつかはこれほど見事に 1 つも持っていない可能性があるため、LEFT JOIN が必要になります。
SELECT Player.WeekRank, Player.Name, COUNT(Game.*) AS WhitewashCount
FROM Player
LEFT JOIN Game ON Game.WinnerPlayerID = Player.PlayerID
WHERE Player.WeekRank >= 10
AND Game.WinnerFrags > Game.TotalFrags/2
GROUP BY Player.WeekRank, Player.Name
ORDER BY Player.WeekRank
まあ、そうではありません。JOIN は、プレイヤーがプレイした各ゲームのレコードを返します。プレイヤーがゲームをプレイしていない場合は、プレイヤー データと NULL ゲーム データを返します。これらの結果は、フラグメント基準に基づいて、オプティマイザーの決定に応じて、結合中または結合後にフィルター処理されます。これにより、frag 基準を満たさないすべてのレコードが削除されます。そのため、これほど壮観な勝利を収めたことのないプレイヤーをグループ化する記録はありません。INNER JOIN の効果的な作成 .... 失敗。
SELECT Player.WeekRank, Player.Name, COUNT(Game.*) AS WhitewashCount
FROM Player
LEFT JOIN Game ON Game.WinnerPlayerID = Player.PlayerID
AND Game.WinnerFrags > Game.TotalFrags/2
WHERE Player.WeekRank >= 10
GROUP BY Player.WeekRank, Player.Name
ORDER BY Player.WeekRank
Frag 基準を JOIN に移動すると、クエリは正しく動作し、ホワイトウォッシュを達成したかどうかに関係なく、その週のトップ 10 のすべてのプレーヤーのレコードが返されます。
結局のところ、短い答えは次のとおりです。
INNER JOIN の状況では、条件をどこに置いてもパフォーマンスの違いはおそらくありません。ただし、結合条件とフィルタリング条件を分離すると、クエリが読みやすくなります。そして、間違った場所で条件を取得すると、LEFT JOIN の結果が大きく損なわれる可能性があります。