首先,使用明確的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情況下,它可能不會使你放置的條件的性能差異。如果您分開加入和過濾條件,查詢更具可讀性。在錯誤的地方獲取條件可能會嚴重影響左連接的結果。