MySQL 中使用EXISTS 與IN 的子查詢:效能最佳化
在MySQL 中使用子查詢時,有兩種常見的方法:使用IN運算子並使用EXISTS 運算子。雖然這兩種方法可以實現相似的結果,但它們在性能上可能表現出顯著差異。
考慮以下兩個子查詢範例:
方法1 (IN):
SELECT * FROM tracker WHERE reservation_id IN ( SELECT reservation_id FROM tracker GROUP BY reservation_id HAVING ( method = 1 AND type = 0 AND Count(*) > 1 ) OR ( method = 1 AND type = 1 AND Count(*) > 1 ) OR ( method = 2 AND type = 2 AND Count(*) > 0 ) OR ( method = 3 AND type = 0 AND Count(*) > 0 ) OR ( method = 3 AND type = 1 AND Count(*) > 1 ) OR ( method = 3 AND type = 3 AND Count(*) > 0 ) )
方法2 (EXISTS):
SELECT * FROM `tracker` t WHERE EXISTS ( SELECT reservation_id FROM `tracker` t3 WHERE t3.reservation_id = t.reservation_id GROUP BY reservation_id HAVING ( METHOD = 1 AND TYPE = 0 AND COUNT(*) > 1 ) OR ( METHOD = 1 AND TYPE = 1 AND COUNT(*) > 1 ) OR ( METHOD = 2 AND TYPE = 2 AND COUNT(*) > 0 ) OR ( METHOD = 3 AND TYPE = 0 AND COUNT(*) > 0 ) OR ( METHOD = 3 AND TYPE = 1 AND COUNT(*) > 1 ) OR ( METHOD = 3 AND TYPE = 3 AND COUNT(*) > 0 ) )
如問題陳述所述,方法 1的執行時間明顯長於方法 2。這是由於兩種方法處理子查詢的方式有根本差異。
IN 運算子:
使用 IN 運算子時,MySQL 執行子查詢多次,主查詢中的每一行一次。在這種情況下,對於追蹤器表中的每一行,都會執行子查詢來確定它是否符合指定的條件。這可能會導致顯著的效能開銷,特別是在子查詢複雜或包含大量資料的情況下。
EXISTS 運算子:
相反,EXISTS 運算子查詢只執行一次。它檢查子查詢結果中是否至少有一個與主查詢中的目前行相符的行。如果存在匹配,則 EXISTS 條件被評估為 true;否則,它是錯誤的。這種方法效率更高,因為它避免了多次從子查詢中檢索所有行的需要。
在IN 和EXISTS 之間進行選擇:
通常,它是建議盡可能使用EXISTS 運算符,因為它在大多數情況下提供更好的性能。以下是一些指導原則,可幫助您做出正確的選擇:
其他注意事項:
以上是MySQL 子查詢:何時應使用 EXISTS 與 IN 以獲得最佳效能?的詳細內容。更多資訊請關注PHP中文網其他相關文章!