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中文网其他相关文章!