簡體   English   中英

WHERE子句或ON子句中的INNER JOIN條件?

[英]INNER JOIN condition in WHERE clause or ON clause?

我今天錯誤地輸入了一個查詢,但它仍然有效,並給出了預期的結果。 我打算運行這個查詢:

SELECT e.id FROM employees e JOIN users u ON u.email=e.email WHERE u.id='139840'

但我不小心跑了這個查詢

SELECT e.id FROM employees e JOIN users u ON u.email=e.email AND u.id='139840'

(注意最后一個子句中的AND而不是WHERE

並且都從用戶ID返回了正確的員工ID。

這兩個查詢有什么區別? 第二種形式是否只加入滿足條件的2個表的成員,而第一個表是否會加入整個表,然后運行查詢? 一個比另一個更有效還是更低效? 這是我缺少的其他東西嗎?

謝謝!

對於這樣的內連接,它們在邏輯上是等價的。 但是,您可以運行join子句中的條件意味着與where子句中的條件不同的情況。

作為一個簡單的例子,假設您像這樣進行左連接;

select x.id
from x
       left join y
         on x.id = y.id
;

這里我們將從x中獲取所有行,無論y中是否存在匹配的id。 現在讓我們假設我們的連接條件增長 - 我們不只是根據id而是在id_type上查找y中的匹配。

select x.id
from x
       left join y
         on x.id = y.id
         and y.id_type = 'some type'
;

無論y中是否存在匹配(id,id_type),這都會給出x中的所有行。

但這是非常不同的:

select x.id
from x
       left join y
         on x.id = y.id
where y.id_type = 'some type'
;

在這種情況下,我們選擇x的所有行並嘗試匹配y中的行。 現在對於y中沒有匹配的行,y.id_type將為null。 因此,不滿足y.id_type ='some type',因此丟棄那些沒有匹配的行,這有效地將其轉換為內連接。

長話短說:對於內連接而言,條件在哪里並不重要,但對於外連接它可以。

優化器會對它們進行相同的處理。 你可以做一個EXPLAIN來證明這一點。

因此,寫一個更清晰的。

SELECT e.id
FROM employees e JOIN users u ON u.email=e.email
WHERE u.id='139840'

在INNER JOIN的情況下,兩個查詢在語義上是相同的,這意味着它們保證具有相同的結果。 如果您使用的是OUTER連接,則兩個查詢的含義可能會有很大差異,但結果會有所不同。

在性能方面,我希望這兩個查詢會產生相同的執行計划。 但是,查詢引擎可能會讓您大吃一驚。 要知道的唯一方法是查看兩個查詢的執行計划。

如果它是外部聯接而不是內部聯接,則會產生意外結果,但是在使用內部聯接時,使用其他聯接條件而不是WHERE子句並沒有什么區別。

在性能方面,他們很可能是相同的,但不能確定。

我和我的同事一起在工作中提出這個問題。 這個響應有點以SQL Server為中心而不是MySQL。 但是,優化器在SQL和MySQL之間的操作應該有相似之處。

一些想法:基本上,如果你必須添加一個WHERE,還需要進行額外的表掃描以驗證每個條件的相等性(使用AND或數據集進行數量級遞增,一個OR,該決策在第一個真實時轉換為條件) - 如果你給出的例子中有一個id指針,反之則非常快,如果你必須找到屬於公司或部門的所有記錄,它就會變得更加模糊,因為你可能有多個記錄。 如果可以應用equals條件,則在使用具有數十億行的AuditLog或EventLog表時,它會更有效。 人們不會真正看到這對小桌子(大約200,000行左右)的巨大好處。

來自:Allesandro Alpi http://suxstellino.wordpress.com/2013/01/07/sql-server-logical-query-processing-summary/

來自:Itzik Ben-Gan http://tsql.solidq.com/books/insidetsql2008/Logical%20Query%20Processing%20Poster.pdf

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM