首先,使用明确的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
这将给我们按名称排序的所有球员谁承担更多的frag在一场比赛中比在游戏放在一起的所有其他球员,而比赛的日期。将两个条件都放在JOIN中可能不会影响性能,因为优化器可能会将过滤作为JOIN的一部分。尽管如此,它确实对LEFT JOIN起作用。比方说,我们正在寻找本周前十名球员有多少赢得了上述保证金。由于它们中的一些可能从来没有这样壮观,所以我们需要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游戏数据。根据碎片标准,这些结果将在JOIN期间或之后得到过滤,具体取决于优化程序的决定。这将消除所有不符合分段标准的记录。所以对于从未有如此壮观胜利的球员来说,将没有记录。有效地创建一个INNER JOIN .... FAIL。
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
一旦我们把断枝标准为JOIN查询将正确的行为,返回记录在本周十大所有玩家,不论他们是否已经取得了粉饰。
所有这一切后,简短的回答是:
对于INNER JOIN情况下,它可能不会使你放置的条件的性能差异。如果您分开加入和过滤条件,查询更具可读性。在错误的地方获取条件可能会严重影响左连接的结果。