例如,假設你有一個這樣的查詢:什麼時候有利於約束SQL Server 2005中的連接?
SELECT *
FROM table1 t1
JOIN table2 t2 ON t1.field1 = t2.field1 AND t1.year = t2.year
JOIN table3 t3 ON t1.field1 = t3.field1 AND t1.year = t3.year
JOIN table4 t4 ON t3.field2 = t4.field2 AND t3.year = t4.year
WHERE t1.year = '2010'
它更快做到這一點:
SELECT *
FROM table1 t1
JOIN table2 t2 ON t1.field1 = t2.field1 AND t1.year = t2.year AND t2.year = '2010'
JOIN table3 t3 ON t1.field1 = t3.field1 AND t1.year = t3.year AND t3.year = '2010'
JOIN table4 t4 ON t3.field2 = t4.field2 AND t3.year = t4.year AND t4.year = '2010'
WHERE t1.year = '2010'
它並不總是顯而易見的,這將是「快」。有時候,SQL Server 2005中的執行計劃說一個比另一個快,這取決於索引。有時它會執行所有散列匹配,這看起來是CPU密集型的,而排序然後是合併連接似乎更加IO密集。考慮到執行計劃的結果,真實世界的結果並不總是反映人們的期望。
有人能爲我澄清一個比另一個更好的簡單場景嗎?或者至少驗證我的理解是否正確?在我看來,如果你加入索引良好的列,那麼不用限制一年或某些其他數據的連接會更有效,因爲它可以使用基於索引的哈希匹配,並且不需要排序並使用臨時表。但是,如果您在兩個查詢中選擇並參與非索引列,那麼添加時間約束會導致更少的行被處理,並導致更快的排序和合並連接,即使它引發了一些(更多? )IO成本。
而且,它困擾着我,從表2不考慮價值的有限的子集,從上表1 where子句中產生的預連接選擇,它似乎從表2選擇所有的行不使用時對連接的限制。由於table1中的行將會受到限制b WHERE t1.year ='2010'且連接受t1.year = t2.year限制,因此不應該認爲連接只需要查看table2,其中year =' 2010' ?
我想知道爲什麼它沒有先查看where子句,並且在連接之前只選擇匹配的行,我相信這背後有一些很好的推理,但它逃脫了我,根據執行計劃中,在這種情況下,從table2查看的行數會發生變化,具體取決於是否將t2.year ='2010'添加到連接中。
預先感謝您,對於長期的問題感到抱歉。我想盡可能清楚。請原諒我的缺乏經驗。
既然你問:「我不知道爲什麼它不看where子句第一「,我想我會告訴你邏輯查詢處理順序如下所示的信息:FROM(此步驟的一個子集創建基於連接和它們的ON篩選等的虛擬表),WHERE,GROUP BY ,HAVING,SELECT(這裏的一部分步驟處理SELECT列表中的元素),然後ORDER BY被最後處理。 (還有幾個子步驟我沒有包括在內。) – 2011-03-28 13:23:50