SQL INNER JOIN
與 OR
:效能瓶頸
最近的效能最佳化工作突顯了一個重要問題:在 OR
條件中使用 INNER JOIN
運算子。 以下查詢舉例說明了這個問題:
<code class="language-sql">SELECT mt.ID, mt.ParentID, ot.MasterID FROM dbo.MainTable AS mt INNER JOIN dbo.OtherTable AS ot ON ot.ParentID = mt.ID OR ot.ID = mt.ParentID</code>
這個查詢被證明很慢。 使用 LEFT JOIN
顯著提高的性能重寫它:
<code class="language-sql">SELECT mt.ID, mt.ParentID, CASE WHEN ot1.MasterID IS NOT NULL THEN ot1.MasterID ELSE ot2.MasterID END AS MasterID FROM dbo.MainTable AS mt LEFT JOIN dbo.OtherTable AS ot1 ON ot1.ParentID = mt.ID LEFT JOIN dbo.OtherTable AS ot2 ON ot2.ID = mt.ParentID WHERE ot1.MasterID IS NOT NULL OR ot2.MasterID IS NOT NULL</code>
修改後的查詢在幾秒鐘內執行,這是一個實質性的改進。 這引起了人們對 OR
在 JOIN
條件下的一般使用的擔憂。
為什麼 JOIN 中的 OR
可能會很慢
核心問題是 OR
條件中的 JOIN
會阻止 SQL Server 最佳化器利用高效的 HASH
或 MERGE
連線。這些最佳化的連接方法通常對於快速查詢執行至關重要。 OR
條件阻止伺服器辨識查詢與兩個單獨的等值連線的等價性:
<code class="language-sql">SELECT * FROM maintable m JOIN othertable o ON o.parentId = m.id UNION SELECT * FROM maintable m JOIN othertable o ON o.id = m.parentId</code>
這會迫使 SQL Server 選擇效率較低的執行計劃,從而導致效能下降。
最佳實務:在 OR
條件下避免 JOIN
雖然沒有嚴格禁止,但在 OR
條件下使用 JOIN
通常會阻礙最佳化並導致效能下降。 對於多個連接條件,單獨的等值連接(如上面所示的 LEFT JOIN
和 UNION
或 LEFT JOIN
和 CASE
語句)通常可以提供卓越的效能。 這使得查詢優化器能夠利用其最有效的演算法。
以上是在 INNER JOIN 條件中使用「OR」是否總是對 SQL 效能不利?的詳細內容。更多資訊請關注PHP中文網其他相關文章!