[英]Where is better to put 'on' conditions in multiple joins? (mysql)
我有多個連接,包括mysql中的左連接。 有兩種方法可以做到這一點。
我可以在每次加入后立即設置“ON”條件:
select * from A join B ON(A.bid = B.ID)join C ON(B.cid = C.ID)join D ON(c.did = D.ID)
我可以將它們全部放在一個“ON”子句中:
select * from A join B join C join D ON(A.bid = B.ID AND B.cid = C.ID AND c.did = D.ID)
哪種方式更好?
如果我在查詢中需要左連接或右連接 ,它是否不同?
對於簡單的用途,MySQL幾乎不可避免地以相同的方式執行它們,因此它是一種偏好和可讀性(這是一個很好的辯論主題)。
但是,對於更復雜的查詢,尤其是具有OUTER JOIN
的聚合查詢,這些查詢有可能成為磁盤和io綁定 - 在不使用帶有OUTER JOIN查詢的WHERE子句時可能會有性能和看不見的含義。
運行8分鍾或.8秒的查詢之間的差異可能最終取決於WHERE
子句,特別是因為它與索引有關( MySQL如何使用索引 ): WHERE
子句是為查詢優化器提供信息的核心部分它需要做它的工作並告訴引擎如何以最有效的方式執行查詢。
“本節討論了處理WHERE子句時可以進行的優化...通過嘗試所有可能性來找到加入表的最佳連接組合。如果ORDER BY和GROUP BY子句中的所有列都來自同一個表,那么該表是加入時首選首選。“
對於連接中的每個表,構造一個更簡單的WHERE來獲得對表的快速WHERE評估,並且還盡快跳過行
一些例子:
全表掃描(類型= ALL),不Using where
EXTRA中的位置
[SQL] SELECT cr.id,cr2.role FROM CReportsAL cr
LEFT JOIN CReportsCA cr2
ON cr.id = cr2.id AND cr.role = cr2.role AND cr.util = 1000
[Err] Out of memory
使用where
優化結果,與指數( Using where
, Using index
):
[SQL] SELECT cr.id,cr2.role FROM CReportsAL cr
LEFT JOIN CReportsCA cr2
ON cr.id = cr2.id
WHERE cr.role = cr2.role
AND cr.util = 1000
515661 rows in set (0.124s)
**** ON / WHERE的組合 - 相同的結果 - EXPLAIN
*******中的相同計划
[SQL] SELECT cr.id,cr2.role FROM CReportsAL cr
LEFT JOIN CReportsCA cr2
ON cr.id = cr2.id
AND cr.role = cr2.role
WHERE cr.util = 1000
515661 rows in set (0.121s)
MySQL通常足夠聰明,能夠找出如上所述的簡單查詢,並且會以類似方式執行它們,但在某些情況下它不會。
外連接查詢性能:
由於LEFT JOIN和RIGHT JOIN都是OUTER JOINS( 這里有很好的深入評論) ,因此產生了笛卡爾積的問題,必須避免使用表掃描,以便盡可能快地消除查詢所需的盡可能多的行盡可能。
WHERE
,索引和查詢優化器一起使用可以完全消除笛卡爾積與小型函數(如AVERAGE
, GROUP BY
, SUM
, DISTINCT
等)一起使用時所帶來的問題。運行時間減少的數量級通過適當的索引來實現。用戶和WHERE子句的使用。
最后
同樣,對於大多數查詢,查詢優化器將以相同的方式執行這些 - 使其成為一種偏好方式,但是當查詢優化變得重要時, WHERE
是一個非常重要的工具。 通過將索引col指定為附加的ON..AND ON子句,我已經看到在某些情況下使用INNER JOIN
會有一些性能提升,但我無法告訴您原因。
將ON子句與它適用的JOIN放在一起。
原因是:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.