[英]SQL order of operations
如果我運行以下SQL查詢
SELECT *
FROM A
LEFT JOIN B
ON A.foo=B.foo
WHERE A.date = "Yesterday"
是否在JOIN
之前或之后評估WHERE
語句?
如果之后,什么是更好的方式編寫此語句,以便只返回"Yesterday"
A
行加入B
?
這取決於數據庫。
在SQL Server上,運行: SET SHOWPLAN_ALL ON
然后運行查詢,您將了解運行時會發生什么。
您對“評估”的想法並不正確,因為SQL是一種聲明性語言。
順便說一下,你可以看到查詢執行計划。 在MySQL中,使用關鍵字describe
為您的查詢添加前綴以查看執行計划。
語義上:在JOIN之后。 但在這種情況下,時序沒有區別,因為它位於JOIN的左側。
正如你已經擁有的那樣,“只有”昨天“中的A行加入了B”。
優化器可以自由地重新組織其操作順序,具體取決於關系代數中的等價。
這只返回A.date =“Yesterday”並加入B,它可以在foo上找到匹配:
SELECT * FROM A
LEFT JOIN B
ON A.foo=B.foo
WHERE A.date="Yesterday"
這將返回所有A而不管任何條件,並加入B,其中A.date =“Yesterday”並且它在foo上找到匹配:
SELECT * FROM A
LEFT JOIN B
ON A.foo=B.foo
AND A.date="Yesterday"
確定滿足查詢的操作順序是為什么特定數據庫的查詢優化器突發奇想。 查詢優化器嘗試根據它可以從查詢中收集的內容以及它手頭有關數據庫的任何統計信息(可能包括表的基數和某些數據分布)來生成一個好的“查詢計划”(操作集)。 。
在您的情況下,答案可能取決於您是否在A.date上有二級索引
查詢優化是一個相當豐富的主題 您正在使用的任何數據庫的文檔將有更多關於它的說明。
取決於索引和統計數據。
您應該顯示查詢的執行路徑,以確定應該應用的優化位置(如果有)。
在SQL Server中:
作為一般經驗法則,在WHERE子句之前評估JOIN子句。
如果在連接部分需要過濾器的復雜連接,我會將它們與我的連接一起編寫
SELECT *
FROM A
LEFT JOIN B
ON A.Foo1 = B.Foo1
And A.Date = 'Yesterday'
OUTER JOIN C
ON B.Foo2 = C.Foo2
JOIN D
ON B.Foo3 = D.Foo3
SELECT *
FROM (SELECT * FROM A WHERE Date = 'Yesterday') A
LEFT JOIN B
ON A.Foo1 = B.Foo1
OUTER JOIN C
ON B.Foo2 = C.Foo2
JOIN D
ON B.Foo3 = D.Foo3
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.